我正在学习 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() 时我遇到了一些麻烦,因为我试图为已经存在的数据库模式创建一个“新对象”。所以对我来说解决方案是
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()