使用 SQL SMO 修复孤立用户?
Posted
技术标签:
【中文标题】使用 SQL SMO 修复孤立用户?【英文标题】:Fixing Orphaned Users with SQL SMO? 【发布时间】:2010-11-27 06:51:09 【问题描述】:有没有办法使用 SQL SMO 修复 SQL 2005/2008 数据库中的孤立用户?
通过枚举用户并查找空的User.Login
属性,您可以相对容易地找到孤立用户:
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
public static IList<string> GetOrphanedUsers(Server smoServer, string database)
Database db = smoServer.Databases[database];
List<string> orphanedUsers = new List<string>();
foreach (User user in db.Users)
if (!user.IsSystemObject && user.Login == string.Empty)
orphanedUsers.Add(user.Name);
return orphanedUsers;
不幸的是,修复并不像将User.Login
属性设置为匹配的服务器登录名那么简单。 User.Login
确实有一个 setter,但我不知道有一种方法可以将它传播回服务器。它仅在您创建新的User
时才可用。
我考虑从数据库中删除用户并将服务器登录重新绑定到数据库,但随之而来的是额外的复杂性。诸如重新分配默认架构、角色以及如果他们在数据库中拥有架构等复杂情况,当您通过这些更改进行级联时,您会遇到更多麻烦。足以让您想要内联 SQL 并完成它:
ServerConnection server = new ServerConnection("MyBox\SQLInstance");
Database db = server.Databases["MyDatabase"];
db.ExecuteNonQuery("sp_change_users_login 'auto_fix', 'ORPHANED_USERNAME'")
但是,我不希望内联对系统存储过程的调用。
有什么建议吗?
【问题讨论】:
【参考方案1】:不幸的是,在提供应该可用的方法方面,SMO 并不比 SQL-DMO 好多少。您将不得不使用内联 SQL:
db.ExecuteNonQuery("sp_change_users_login 'auto_fix', 'ORPHANED_USERNAME'")
或
db.ExecuteNonQuery("sp_change_users_login 'update_one', 'ORPHANED_USERNAME', 'ORPHANED_USERNAME'")
【讨论】:
这几乎就是我从 gbn 的回答和迄今为止的 cmets 得出的结论。这感觉像是在偷答案,但据我所知,这是正确的答案。 请注意,MSDN 文档msdn.microsoft.com/en-us/library/ms174378.aspx 指出,此方法将在 SQL Server 的未来版本中删除,并用于使用 Alter 用户,正如 Yoopergeek 下面所述SMO。【参考方案2】:来自 T-SQL ALTER LOGIN ... WITH LOGIN = ...
登录 = 登录名
将用户重新映射到 通过更改用户的另一个登录 安全标识符 (SID) 以匹配 登录的 SID。
现在,我还没有尝试过,因为我会跨服务器同步 SID(现在很少使用 SQL 登录)
但是,这映射到User.Alter Method。
所以,它可能会起作用......
如果它不喜欢使用相同的登录名,我认为您可以映射到另一个登录名并返回。
【讨论】:
很好的建议。不知道我是如何错过 User.Alter() 方法的。但是,它看起来像设置 User.Login,然后调用 User.Alter() 是不允许的。它抛出一个 FailedOperationException 说明:“用户 'MyOrphanedUser' 的更改失败。” FailedOperationException 有一个 SmoException 类型的内部异常,它声明:“不允许修改 User 对象的 Login 属性。您必须删除并重新创建具有所需属性的对象。”也许根本不可能通过 SMO API 解除孤儿? 只做 Smo.Database.ExecuteNonQuery("Alter User FOO With Login FooLogin"). 这就是我最初希望避免的——将 SQL 内联到数据库中。但是,这就是我最终选择的路线。但是,我使用的是我提到的问题的“sp_change_users_login”系统存储过程。【参考方案3】:对我来说,这个语法很好用
db.ExecuteNonQuery("sp_change_users_login 'Auto_Fix', 'login_from_Report', NULL, 'p@ssword123!'")
我在这里找到它:http://dbadiaries.com/using-sp_change_users_login-to-fix-sql-server-orphaned-users#sthash.Q85ewEr9.dpuf
【讨论】:
以上是关于使用 SQL SMO 修复孤立用户?的主要内容,如果未能解决你的问题,请参考以下文章