0

我正在创建一个可以重命名数据库的 PowerShell 函数。

这工作得很好:

    $sqlServer = "MySqlServer"
    $currentDbName = "MyDB"
    $sqlConnectionString = "Server='$sqlserver';Database='$currentDbName';Integrated Security=True"
    $sqlQueries = `
        "ALTER DATABASE [$currentDbName] SET SINGLE_USER WITH ROLLBACK IMMEDIATE",`
        "EXEC sp_renamedb '$currentDbName', '$NewName'",`
        "ALTER DATABASE [$NewName] SET MULTI_USER", `
        "ALTER DATABASE [$NewName] MODIFY FILE (NAME = $currentDbName, NEWNAME = $NewName)", `
        "ALTER DATABASE [$NewName] MODIFY FILE (NAME = $($currentDbName)_Log, NEWNAME = $($NewName)_Log)"
    $conn=new-object System.Data.SqlClient.SQLConnection($sqlConnectionString)
    try {
        $conn.Open()
        $sqlQueries | % {
            $cmd = $conn.CreateCommand()
            $cmd.CommandText = $_
            $cmd.ExecuteScalar()
            Write-Host "    Executed: $_" -ForegroundColor Gray
        }
    }
    catch{
        $actualError = $error[0]

        throw $actualError
    }
    finally{
        if($conn) {
            $conn.Close()
            $conn.Dispose()
        }
    }

此脚本重命名数据库和数据文件(假设只有一个数据文件)。

但此脚本不重命名文件的物理名称,也不支持重命名多个数据文件。

怎么还能重命名数据库的物理文件?

请注意,数据库架构不在我的控制范围内,我无法在数据库中添加存储过程。

[编辑]脚本远程运行,而不是在 SQL Server 框中。

4

1 回答 1

0

根据MSDN,您需要包含 FILENAME 子句

MODIFY FILE ( NAME = logical_file_name, FILENAME = ' new_path/os_file_name ' )

我相信流程是:

  1. 重命名数据库和数据文件名
  2. 使数据库脱机
  3. 重命名物理文件
  4. 更新数据库文件名以指向新的物理文件
  5. 使数据库重新联机

我已经尝试将您的脚本更新为我认为应该阅读的方式,我没有任何地方可以测试它,因此请确保您在“安全”的地方进行测试。

$sqlServer = "MySqlServer"
$currentDbName = "MyDB"
$sqlConnectionString = "Server='$sqlserver';Database='$currentDbName';Integrated Security=True"

$PhysicalLocal = "C:\Data\"
$PhysicalUNC = "\\$sqlserver\C$\Data\"

$sqlQueries = `
    "ALTER DATABASE [$currentDbName] SET SINGLE_USER WITH ROLLBACK IMMEDIATE",`
    "EXEC sp_renamedb '$currentDbName', '$NewName'",`
    "ALTER DATABASE [$NewName] SET MULTI_USER", `
    "ALTER DATABASE [$NewName] MODIFY FILE (NAME = $currentDbName, NEWNAME = $NewName)", `
    "ALTER DATABASE [$NewName] MODIFY FILE (NAME = $($currentDbName)_Log, NEWNAME = $($NewName)_Log)", `
    "ALTER DATABASE [$currentDbName] SET offline"

$sqlQueriesRename = `
    "ALTER DATABASE [$NewName] MODIFY FILE (NAME = $NewName, FILENAME = $($PhysicalLocal\$NewName).mdf", `
    "ALTER DATABASE [$NewName] MODIFY FILE (NAME = $($NewName)_Log, FILENAME = $($PhysicalLocal\$NewName)_Log.ldf)", `
    "ALTER DATABASE [$currentDbName] SET online"

$conn=new-object System.Data.SqlClient.SQLConnection($sqlConnectionString)
try {
    $conn.Open()

    # Rename the database, leave in offline state
    $sqlQueries | % {
        $cmd = $conn.CreateCommand()
        $cmd.CommandText = $_
        $cmd.ExecuteScalar()
        Write-Host "    Executed: $_" -ForegroundColor Gray
    }

    # Rename the physical files
    Rename-Item $(Join-Path -Path $PhysicalUNC -ChildPath $($currentDbName).mdf) $($NewName).mdf
    Rename-Item $(Join-Path -Path $PhysicalUNC -ChildPath $($currentDbName)_Log.ldf) $($NewName)_Log.ldf

    # Rename the database files to match the physical ones
    $sqlQueriesRename | % {
        $cmd = $conn.CreateCommand()
        $cmd.CommandText = $_
        $cmd.ExecuteScalar()
        Write-Host "    Executed: $_" -ForegroundColor Gray
    }
}
catch{
    $actualError = $error[0]
    throw $actualError
}
finally{
    if($conn) {
        $conn.Close()
        $conn.Dispose()
    }
}
于 2013-05-30T09:13:45.790 回答