如何解决在运行 SQL Server 的服务器之间移动数据库时的权限问题
概要
本文描述如何映射标准登录和集成登录来解决在运行 SQL Server 的服务器之间移动数据库时的权限问题。
更多信息
当您将数据库从一个运行 SQL Server 的服务器移到另一个运行 SQL Server 的服务器时,master 数据库中登录的安全标识号 (SID) 与用户数据库中用户的 SID 可能不匹配。默认情况下,SQL Server 7.0、SQL Server 2000 和 SQL Server 2005 会提供 sp_change_users_login 系统存储过程来映射这些不匹配的用户。但是,sp_change_users_login 存储过程仅能用于映射标准的 SQL Server 登录,而且需要一次对一个用户执行这些映射。有关 sp_change_users_login 存储过程的更多信息,请参阅 SQL Server 7.0、SQL Server 2000 和 SQL Server 2005 联机丛书中的“sp_change_users_login”主题。
在 SQL Server 7.0 或更高版本中,您可以使用 SID 来维护 master 数据库中的登录和用户数据库中的用户之间的映射。此映射是维护用户数据库中登录的正确权限所必需的。如果丢失此映射,登录将发生权限问题,其中包括但不限于以下问题:
•如果新服务器上不存在 SQL Server 登录,而用户尝试登录,该用户可能会收到以下错误消息:
Server:Msg 18456, Level 16, State 1
Login failed for user '%ls'.
•如果新服务器上存在 SQL Server 登录,但 master 数据库中的 SID 与用户数据库中的 SID 不相同,则用户可以成功登录到 SQL Server;但是,当用户尝试访问该数据库时,可能会收到以下错误消息:
Server:Msg 916, Level 14, State 1, Line1
Server user '%.*ls' is not a valid user in database '%.*ls'.
注意:在 SQL Server 2005 中,用户可能会收到以下错误消息:
服务器用户“%s”不是数据库“%s”中的有效用户。请先将该用户帐户添加到数据库中。
有关 SQL Server 7.0 安全模型的更多信息,请参阅“Microsoft SQL Server 7.0 Security”(Microsoft SQL Server 7.0 安全性)白皮书。要查看此白皮书,请访问下面的 Microsoft 网站:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsql7/html/sql7security.asp
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsql7/html/sql7security.asp)
有关 SQL Server 2000 安全模型的更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
322712 (http://support.microsoft.com/kb/322712/) Microsoft SQL Server 2000 S322712 安全功能和最佳做法
要下载 Mapsids.exe 文件,请使用下面的下载链接:
Mapsids.exe
http://download.microsoft.com/download/sqlsvr2000/utility/5.0/win98me/en-us/Mapsids.exe
(http://download.microsoft.com/download/sqlsvr2000/utility/5.0/win98me/en-us/mapsids.exe)
限制
•如果 sysusers 表中有用户没有以计算机名或拥有对象的域名作为前缀,而应用程序中使用包含两个部分的名称 username.objectname 引用了这些对象,则应用程序可能会中断,因为当 sp_sidmap 存储过程在 sysxlogins 表中出现时,它会以计算机名或域名作为前缀重命名这些用户。要解决此问题,请在 sp_sidmap 存储过程完成后,将 sysusers 表中受影响的用户重命名为它们原来的名称,或者与您的主要支持提供商联系。
•本文未涉及别名。您必须手动管理别名。
•如果新的 SQL Server 服务器上不存在标准的 SQL Server 登录,则会添加密码为空的登录。因此,您可能需要更改这些登录的密码。
•如果用户是在用户数据库中创建的,而且该用户的名称不同于 sysxlogins 表中显示的名称,则无法知道该用户的相应登录。因此,在执行 sp_sidmap 存储过程之前:
1.将该用户拥有的所有对象转移到一个临时数据库。
2.删除该用户,添加具有正确名称的用户,然后再移回该用户的所有对象。
•如果用户不具有对应的登录,而且也没有以本地计算机名或域名作为前缀,您将收到有关该用户的一则消息。该消息指出,需要首先在 Windows 级别添加该用户,再将其作为登录添加到 SQL Server;然后,您必须要再次执行 sp_sidmap 存储过程。
•如果用户以域名或本地 Windows 服务器名作为前缀,但 sysxlogins 表中不存在相应的登录,该存储过程会尝试将其作为新登录添加到 SQL Server。如果该 Windows 用户不存在,则将在结果窗口中生成一条输出消息,然后在它首次添加该 Windows 用户后手动创建登录。
•如果 sysusers 表中的某一用户有多个登录,您将在结果文件中看到一则输出消息,它会列出具有相同用户名的所有登录。此时,您必须手动干预,以确保该用户仅对应于一个登录。
示例:如果 sysusers 表中有一个名称为“johndoe”的用户,而 sysxlogins 表中有名为诸如“Test\johndoe”和“Test2\johndoe”的登录,则当运行存储过程时,您将收到一条消息,指出其中一个用户具有多个登录,系统管理员必须从中选择一个。只有在这种情况下,您才必须运行本文提供的第二个存储过程 sp_prefix_sysusersname。另外,Readme.txt 文件中也详细介绍了这种情况。
映射标准登录和集成登录
当您将数据库从一个运行 SQL Server 的服务器移到另一个运行 SQL Server 的服务器后,请按照下列步骤操作,以尽量减少用户干预:
1.确保对于数据库的 sysusers 表中的每一个用户,master 数据库的 sysxlogins 表中都有一个登录。
注意:要添加标准 SQL Server 登录,请参阅 SQL Server 联机丛书中的“sp_addlogin”主题。要添加集成的 SQL Server 登录,请参阅 SQL Server 联机丛书中的“sp_grantlogin”主题。
2.下载 MapSids.exe 文件,然后解压缩 Sp_sidmap.sql 和 Readme.txt 文件。
3.以系统管理员身份登录到运行 SQL Server 的服务器,然后在用户数据库中运行 Sp_sidmap.sql 文件。运行 Sp_sidmap.sql 文件会创建两个存储过程:sp_sidmap 和 sp_prefix_sysusersname。
4.确保除了运行这些存储过程的用户之外,没有其他任何用户访问该数据库。
5.确保“查询分析器”窗口以文本格式(而不是网格格式)显示结果。为此,请按 Ctrl^T 键,或者单击查询,然后单击“文本显示结果”。这是非常重要的,它使您可以在一个窗口中查看结果和信息性消息,并将输出保存到文本文件中。稍后可能需要使用该文件来解析某些映射。
6.由于您无法验证参数是否已正确传递,因此请确保将参数正确地传递到 sp_sidmap 存储过程:
EXEC sp_SidMap @old_domain = old_domain_name, @new_domain = new_domain_name, @old_server = old_server_name, @new_server = new_server_name
适当地替换新旧域名和服务器名的值。
7.将结果保存在一个文件中,然后按照 Readme.txt 文件中提供的指导操作。
注意:当您运行这些存储过程时,数据库中唯一变化的表是 sysusers 表。如果您需要返回到开始时的状态,请从备份中还原数据库或者重新附加数据库。
参考
有关更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
274188 (http://support.microsoft.com/kb/274188/) PRB:联机丛书中的“孤立用户疑难解答”主题不完整
246133 (http://support.microsoft.com/kb/246133/) 如何在 SQL Server 实例之间传输登录和密码
168001 (http://support.microsoft.com/kb/168001/) 还原数据库后数据库上的用户登录和权限可能不正确
298897 (http://support.microsoft.com/kb/298897/) 示例:Mapsids.exe 有助于在移动数据库时在用户数据库和 master 数据库之间映射 SID