你目前正处于脱机状态,正在等待 Internet 重新连接

如何解决在运行 SQL Server 的服务器之间移动数据库时的权限问题

本文的发布号曾为 CHS240872
概要
本文描述如何映射标准登录和集成登录来解决在运行 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 网站:有关 SQL Server 2000 安全模型的更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
322712Microsoft SQL Server 2000 S322712 安全功能和最佳做法

限制

  • 如果 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_sidmapsp_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 知识库中相应的文章:
274188PRB:联机丛书中的“孤立用户疑难解答”主题不完整
246133 如何在 SQL Server 实例之间传输登录和密码
168001 还原数据库后数据库上的用户登录和权限可能不正确
298897 示例:Mapsids.exe 有助于在移动数据库时在用户数据库和 master 数据库之间映射 SID
属性

文章 ID:240872 - 上次审阅时间:05/17/2011 19:30:00 - 修订版本: 8.0

  • Microsoft SQL Server 2000 标准版
  • Microsoft SQL Server 2000 64-bit Edition
  • Microsoft SQL Server 7.0 标准版
  • Microsoft SQL Server 2005 Developer Edition
  • Microsoft SQL 2005 Server Enterprise
  • Microsoft SQL Server 2005 Express Edition
  • Microsoft SQL Server 2005 Standard Edition
  • Microsoft SQL 2005 Server Workgroup
  • kbsqldeveloper kbhowtomaster KB240872
反馈
cript>