PowerShell脚本的数据库架构所有者问题

时间:2013-09-24 21:53:48

标签: sql-server-2008 powershell

我正在学习powershell脚本并编写了一个简单的脚本来从备份文件中恢复sql数据库。恢复工作很好,但是现在我需要脚本从新恢复的数据库中删除几个用户并将其添加回来。如果它们未被列为该特定数据库中任何模式的所有者,则没有问题。

我遇到的问题是,如果它们被列为架构所有者,那么我的脚本将抛出此异常

Exception calling "Drop" with "0" argument(s): "Drop failed for User 'MyUser'. "
At line:1 char:1
+ $user.Drop()
+ ~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : FailedOperationException

我已经尝试过这段代码将架构的所有者更改为dbo,但我仍然得到了例外。奇怪的是,如果我在更改所有者后检查powershell中的架构详细信息,我会将所有者视为dbo,但如果我检查sql server management studio中的架构所有者,则即使在刷新数据库后,所有者仍然是旧所有者

PS E:\MyScripts> $server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "(local)"
PS E:\MyScripts> $server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "(local)"
PS E:\MyScripts> $db = $server.Databases["MyDB"]
PS E:\MyScripts> $sch = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Schema -argumentlist $db, "MySchema"
PS E:\MyScripts> $sch.Owner = "[dbo]"

整个脚本看起来像这样

#load assemblies
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null

#Need SmoExtended for backup
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null

$server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "(local)"

$db = $server.Databases["MyDB"];
$user = $db.Users["MyUser"];
$sch = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Schema -argumentlist $db, "MySchema"
$sch.Owner = "[dbo]";
$user.Drop();

为我工作的解决方案 在玩了一些脚本和下面的建议后,我发现问题是我在更新所有者后没有在架构上调用.Alter()。我最初使用.Alter()时遇到了一些麻烦,因为当一个已存在时,我试图为数据库模式创建一个“New-Object”。所以我的解决方案是

PS E:\MyScripts> [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
PS E:\MyScripts>
PS E:\MyScripts> [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
PS E:\MyScripts> [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
PS E:\MyScripts> [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null
PS E:\MyScripts>
PS E:\MyScripts> $server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "(local)"
PS E:\MyScripts> $db = $server.Databases["MyDB"]
PS E:\MyScripts> $db = $server.Databases["MyExistingSchema"]
PS E:\MyScripts> $db.Schemas["Cadence"].Owner = "MyUser"
PS E:\MyScripts> $db.Schemas["Cadence"].Alter()

2 个答案:

答案 0 :(得分:0)

设置新所有者后,尝试在$ sch对象上调用alter方法:

$sch.Owner = "[dbo]"
$sch.Alter()

答案 1 :(得分:0)

将拥有架构从一个用户更改为另一个用户

$srv = new-object ('Microsoft.SqlServer.Management.Smo.Server') $servername
$database = $srv.Databases[$dbname]
$sch = $database.Schemas["db_owner"]
$sch.Owner = "dbo"
$sch.Alter()