sql server 7.0 数据转换服务 (dts) 对象传输功能可在两台服务器之间传输登录和用户,但它不传输 sql server 验证登录的密码。要从一台运行 sql server 7.0 的服务器向另一台运行 sql server 7.0 的服务器传输登录和密码,请按照本文“在 master 数据库中创建和运行存储过程”一节中的说明操作。您将在源服务器上创建 sp_help_revlogin 存储过程。此过程将生成一个脚本,您可以在目标服务器上运行该脚本,以重新创建带有原始安全标识号 (sid) 的登录,并保留当前的密码。
返回页首
如何从 sql server 7.0 向 sql server 2000 或者在正运行 sql server 2000 的服务器之间传输登录和密码要从 sql server 7.0 服务器向 sql server 2000 的一个实例或者在 sql server 2000 的两个实例之间传输登录和密码,可以使用 sql server 2000 中新的 dts package transfer logins task(dts 包传输登录任务)。要使用此任务,请执行以下步骤:
1.连接到 sql server 2000 目标服务器,移动到 sql server 企业管理器中的数据转换服务,展开此文件夹,右键单击本地程序包,然后单击新增程序包。2.在 dts 程序包设计器打开后,单击任务菜单上的传输登录任务。根据需要完成有关源、目标和登录选项卡的信息。
重要说明:sql server 2000 目标服务器不能运行 64 位版本的 sql server 2000。64 位版本 sql server 2000 的 dts 组件不可用。如果要从其他计算机上的 sql server 实例中导入登录,您的 sql server 实例必须在域帐户下运行才能完成此任务。
注意:您可以使用 dts 方法或本文“在 master 数据库中创建和运行存储过程”一节中的脚本,从 sql server 7.0 向 sql server 2000 或者在 sql server 2000 的实例之间传输登录。dts 方法将传输密码,但不传输原始 sid。如果登录不是使用原始 sid 创建的,而且用户数据库也被传输到一台新服务器,则该数据库用户将被从该登录中孤立出去。要传输原始 sid 并回避孤立用户,请使用本文下一节中的脚本代替 dts 方法。返回页首
在 master 数据库中创建和运行存储过程请查看本文末尾的备注,以了解有关下列步骤的重要信息。
1.在源 sql server 上运行以下脚本。此脚本可在 master 数据库中创建名称分别为 sp_hexadecimal 和 sp_help_revlogin 的两个存储过程。请在创建完过程之后继续执行第 2 步。
注意:下面的过程取决于 sql server 系统表。这些表的结构在 sql server 的不同版本之间可能会有变化,请不要直接从系统表中选择。
----- begin script, create sp_help_revlogin procedure -----use mastergoif object_id ('sp_hexadecimal') is not null drop procedure sp_hexadecimalgocreate procedure sp_hexadecimal @binvalue varbinary(256), @hexvalue varchar(256) outputasdeclare @charvalue varchar(256)declare @i intdeclare @length intdeclare @hexstring char(16)select @charvalue = '0x'select @i = 1select @length = datalength (@binvalue)select @hexstring = '0123456789abcdef'while (@i <= @length)begin declare @tempint int declare @firstint int declare @secondint int select @tempint = convert(int, substring(@binvalue,@i,1)) select @firstint = floor(@tempint/16) select @secondint = @tempint - (@firstint*16) select @charvalue = @charvalue + substring(@hexstring, @firstint+1, 1) + substring(@hexstring, @secondint+1, 1) select @i = @i + 1endselect @hexvalue = @charvaluegoif object_id ('sp_help_revlogin') is not null drop procedure sp_help_revlogingocreate procedure sp_help_revlogin @login_name sysname = null asdeclare @name sysnamedeclare @xstatus intdeclare @binpwd varbinary (256)declare @txtpwd sysnamedeclare @tmpstr varchar (256)declare @sid_varbinary varbinary(85)declare @sid_string varchar(256)if (@login_name is null) declare login_curs cursor for select sid, name, xstatus, password from master..sysxlogins where srvid is null and name <> 'sa'else declare login_curs cursor for select sid, name, xstatus, password from master..sysxlogins where srvid is null and name = @login_nameopen login_cursfetch next from login_curs into @sid_varbinary, @name, @xstatus, @binpwdif (@@fetch_status = -1)begin print 'no login(s) found.' close login_curs deallocate login_curs return -1endset @tmpstr = '/* sp_help_revlogin script 'print @tmpstrset @tmpstr = '** generated ' + convert (varchar, getdate()) + ' on ' + @@servername + ' */'print @tmpstrprint ''print 'declare @pwd sysname'while (@@fetch_status <> -1)begin if (@@fetch_status <> -2) begin print '' set @tmpstr = '-- login: ' + @name print @tmpstr if (@xstatus & 4) = 4 begin -- nt authenticated account/group if (@xstatus & 1) = 1 begin -- nt login is denied access set @tmpstr = 'exec master..sp_denylogin ''' + @name + '''' print @tmpstr end else begin -- nt login has access set @tmpstr = 'exec master..sp_grantlogin ''' + @name + '''' print @tmpstr end end else begin -- sql server authentication if (@binpwd is not null) begin -- non-null password exec sp_hexadecimal @binpwd, @txtpwd out if (@xstatus & 2048) = 2048 set @tmpstr = 'set @pwd = convert (varchar(256), ' + @txtpwd + ')' else set @tmpstr = 'set @pwd = convert (varbinary(256), ' + @txtpwd + ')' print @tmpstrexec sp_hexadecimal @sid_varbinary,@sid_string out set @tmpstr = 'exec master..sp_addlogin ''' + @name + ''', @pwd, @sid = ' + @sid_string + ', @encryptopt = ' end else begin -- null passwordexec sp_hexadecimal @sid_varbinary,@sid_string out set @tmpstr = 'exec master..sp_addlogin ''' + @name + ''', null, @sid = ' + @sid_string + ', @encryptopt = ' end if (@xstatus & 2048) = 2048 -- login upgraded from 6.5 set @tmpstr = @tmpstr + '''skip_encryption_old''' else set @tmpstr = @tmpstr + '''skip_encryption''' print @tmpstr end end fetch next from login_curs into @sid_varbinary, @name, @xstatus, @binpwd endclose login_cursdeallocate login_cursreturn 0go ----- end script -----
2.在创建 sp_help_revlogin 存储过程之后,请从源服务器上的查询分析器中运行 sp_help_revlogin 过程。sp_help_revlogin 存储过程可同时用于 sql server 7.0 和 sql server 2000。sp_help_revlogin 存储过程的输出是登录脚本,该脚本可创建带有原始 sid 和密码的登录。保存输出,然后将其粘贴到目标 sql server 上的查询分析器中,并运行它。例如:
exec master..sp_help_revlogin
返回页首
备注•在目标 sql server 上运行输出脚本之前,请认真查看此脚本。如果必须将登录传输到与 sql server 源实例不在同一个域中的 sql server 实例,请编辑由 sp_help_revlogin 过程生成的脚本,并在 sp_grantlogin 语句中将域名替换为新的域名。由于在新域中被授予访问权的集成登录与原域中的登录具有不同的 sid,因此数据库用户将被从这些登录中孤立出去。要解决这些孤立用户,请参见以下项目符号项中引用的文章。如果在同一个域中的 sql server 实例之间传输集成登录,则会使用相同的 sid,而且用户不太可能被孤立。•在移动登录之后,用户将不再具有访问已被同时移动的数据库的权限。此问题称为“孤立用户”。如果尝试将访问此数据库的权限授予该登录,则可能会失败,这表明该用户已存在:
microsoft sql-dmo (odbc sqlstate:42000) error 15023:user or role '%s' already exists in the current database.有关如何将登录映射到数据库用户以解决孤立的 sql server 登录和集成登录的说明,请参见以下 microsoft 知识库文章: 240872 how to:在 sql 服务器之间移动数据库时如何解决权限问题
有关使用 sp_change_users_login 存储过程逐个解决孤立用户(仅能解决从标准 sql 登录中孤立出去的用户)的说明,请参见以下 microsoft 知识库文章: 274188 prb: "troubleshooting orphaned users" topic in books online is incomplete •如果传输登录和密码是向运行 sql server 的新服务器移动数据库的一部分,请参见以下 microsoft 知识库文章,以了解对所涉及的工作流程和步骤的说明: 314546 how to: move databases between computers that are running sql server •能够这样做的原因在于:sp_addlogin 系统存储过程中的 @encryptopt 参数允许通过使用加密密码来创建登录。有关此过程的更多信息,请参见 sql server 联机图书中的“sp_addlogin (t-sql)”主题。•默认情况下,只有 sysadminfixed 服务器角色的成员可以从 sysxlogins 表中进行选择。除非 sysadmin 角色的成员授予了必要的权限,否则最终用户将无法创建或运行这些存储过程。•此方法不会尝试传输特定登录的默认数据库信息,因为默认数据库并不始终存在于目标服务器中。要为某个登录定义默认数据库,您可以使用 sp_defaultdb 系统存储过程,并将登录名和默认数据库作为参数传递给该过程。有关使用此过程的更多信息,请参见 sql server 联机图书中的“sp_defaultdb”主题。•在 sql server 实例之间传输登录的过程中,如果源服务器的排序顺序不区分大小写,而目标服务器的排序顺序区分大小写,则在将登录传输到目标服务器后,必须在密码中用大写形式输入所有字母字符。如果源服务器的排序顺序区分大小写,而目标服务器的排序顺序不区分大小写,则无法通过使用本文概述的过程传输的登录进行登录,除非原始密码不包含字母字符,或者原始密码中的所有字母字符都是大写字符。如果两个服务器都区分大小写或者都不区分大小写,则不会出现此问题。这是 sql server 处理密码的方式所带来的副作用。有关更多信息,请参见 sql server 7.0 联机图书中的“effect on passwords of changing sort orders”(更改排序顺序对密码的影响)主题。•当在服务器上运行 sp_help_revlogin 脚本的输出时,如果该服务器已经定义了一个登录,且该登录名与脚本输出中的某个登录的名称相同,则在执行 sp_help_revlogin 脚本的输出时,可能会看到下面的错误信息:
server:msg 15025, level 16, state 1, procedure sp_addlogin, line 56
the login 'test1' already exists.
同样,如果此服务器上存在其他登录,且其 sid 值与您要尝试添加的登录相同,则会收到以下错误信息:
server:msg 15433, level 16, state 1, procedure sp_addlogin, line 93
supplied parameter @sid is in use.
因此,您必须仔细查看这些命令的输出,检查 sysxlogins 表的内容,并相应地解决这些错误。•特定登录的 sid 值被用作在 sql server 中实现数据库级别访问的基础。因此,如果同一登录在该数据库级别(在该服务器上的两个不同数据库中)有两个不同的 sid 值,则此登录将仅能访问其 sid 与该登录的 syslogins 中的值相匹配的数据库。如果所讨论的两个数据库已从两个不同的服务器合并在一起,则可能出现这种情形。要解决此问题,需要使用 sp_dropuser 存储过程从具有不匹配 sid 的数据库中手动删除所讨论的登录,然后再使用 sp_adduser 存储过程添加它。