此问题出现在数据库的移值上。移值后,数据库的登陆名和数据库用户名孤立,原数据中,用建立的用户名密码登陆可以访问数据库,但是移值后就不能访问了。而且如果您尝试向该登录帐户授予数据库访问权限,则会因该用户已经存在而出现以下错误信息:     ‘该登录已经在另一个用户名下拥有帐户’。

产生错误的原因是:
            在您向目标服务器传输登录帐户和密码后,您的用户可能还无法访问数据库。登录帐户与用户是靠安全识别符   (SID)   关联在一起的;在您移动数据库后,如果   SID   不一致,SQL   Server   可能会拒绝用户访问数据库。此问题称为孤立用户。如果您使用  SQL   Server   2000   DTS   传输登录功能来传输登录帐户和密码,就可能会产生孤立用户。此外,被允许访问与源服务器处于不同域中的目标服务器的集成登录帐户,也会导致出现孤立用户。

场景1:无法登陆原实例,如果多个用户出现孤立情况

场景2:可以登录原实例

【0】 使用T-SQL获取登录名及密码

  1. SELECT 'CREATE LOGIN [' + p.name + '] '
  2. + CASE WHEN p.type IN ( 'U', 'G' ) THEN 'FROM windows '
  3. ELSE ''
  4. END + 'WITH ' + CASE WHEN p.type = 'S'
  5. THEN 'password = '
  6. + master.sys.fn_varbintohexstr(l.password_hash)
  7. + ' hashed, ' + 'sid = '
  8. + master.sys.fn_varbintohexstr(l.sid)
  9. + ', check_expiration = '
  10. + CASE WHEN l.is_expiration_checked > 0
  11. THEN 'ON, '
  12. ELSE 'OFF, '
  13. END + 'check_policy = '
  14. + CASE WHEN l.is_policy_checked > 0
  15. THEN 'ON, '
  16. ELSE 'OFF, '
  17. END
  18. + CASE WHEN l.credential_id > 0
  19. THEN 'credential = ' + c.name
  20. + ', '
  21. ELSE ''
  22. END
  23. ELSE ''
  24. END + 'default_database = '
  25. + p.default_database_name
  26. + CASE WHEN LEN(p.default_language_name) > 0
  27. THEN ', default_language = ' + p.default_language_name
  28. ELSE ''
  29. END
  30. FROM sys.server_principals p
  31. LEFT JOIN sys.sql_logins l
  32. ON p.principal_id = l.principal_id
  33. LEFT JOIN sys.credentials c
  34. ON l.credential_id = c.credential_id
  35. WHERE p.type IN ( 'S', 'U', 'G' )
  36. --AND p.name NOT IN ( 'sa')
  37. AND p.name NOT LIKE '%##%'
  38. AND p.name NOT LIKE '%NT SERVICE%'
  39. AND p.name NOT LIKE '%NT AUTHORITY%'

【1】查看解决孤立用户

以下是解决办法:
 在目标服务器上打开查询分析器,然后在您移动的用户数据库中运行以下代码:

  1. 1】查找当前库的孤立用户:
  2.  
  3. use db_name;
  4. exec sp_change_users_login 'REPORT';
  5.  
  6. 2】新建与孤立用户同名登录名后,进行新登录名与孤立用户的更新联合
  7.  
  8. Use db_name;
  9. sp_change_users_login 'update_one' , 'user_name' , 'login_name'
  10.  
  11. --查看当前数据库中是否存在孤立用户(只有用户,没有对应的登录名)
    exec sp_change_users_login @action='Report'
  12.  
  13. -- 对孤立用户连接到现有的登录名
    use mytest;
    exec sp_change_users_login @action='update_one',
    @usernamepattern='kk', --数据库孤立用户
    @loginname='kk'; --关联到sql server登录名 go
  1. --也可以使用2005之后的新语法替代SP_CHANGE_USERS_LOGIN ALTER USER MarketUser WITH Login = MarketUser
  1. 一般问题就会解决。
    举例:
    sp_change_users_login 'update_one' , 'test' , 'test'
  1.  
  2. 3】可以用登录名登录,但无法访问数据库
  3.  
  4. 如果一个用户是孤立用户,数据库用户可以成功登录到服务器,但却无权访问数据库。如果您尝试向该登录帐户授予数据库访问权限,则会因该用户已经存在而出现以下错误信息:
  5. Microsoft SQL - DMO (ODBC SQLState: 42000 ) Error 15023 : User or role ' %s ' already exists in the current database .
  6. 或是登陆名对应该的用户改成了dbo,则在sa下执行一下以下代码:
  7.  
  8. exec sp_changedbowner ' sa '

  9. 然后再执行:
  10. Use db_name;
  11. sp_change_users_login ' update_one ' , ' user_name' , 'login_name '
  12. 一般问题就会解决了。

场景1:无法登陆原实例,如果多个用户出现孤立情况

  1. --如果存在同名的登录用户就绑定,不存在就创建(创建时候密码为空)并绑定
  2. USE [GPOSDB] --要解决孤立用户的数据库名
  3. GO
  4. CREATE PROCEDURE [dbo].[sp_fix_orphaned_users]
  5. AS
  6. BEGIN
  7. DECLARE @UserName NVARCHAR(64)
  8.  
  9. CREATE TABLE #SqlLoginUser
  10. (
  11. UserName SYSNAME ,
  12. UserId INT IDENTITY(1, 1)
  13. )
  14.  
  15. INSERT INTO #SqlLoginUser( UserName ) SELECT [name] FROM SYS.[sql_logins]
  16.  
  17. CREATE TABLE #OrphanedUser
  18. (
  19. UserName SYSNAME ,
  20. UserId INT
  21. )
  22.  
  23. INSERT INTO #OrphanedUser EXEC sp_change_users_login @Action = 'Report';
  24.  
  25. DECLARE Cur_OrphanedUsers CURSOR
  26. FOR
  27. SELECT UserName
  28. FROM #OrphanedUser;
  29. OPEN Cur_OrphanedUsers;
  30. FETCH NEXT FROM Cur_OrphanedUsers INTO @UserName;
  31. WHILE ( @@FETCH_STATUS = 0 )
  32. BEGIN
  33. IF ( @UserName IN ( SELECT [UserName]
  34. FROM [#SqlLoginUser] ) )
  35. BEGIN
  36. EXEC sp_change_users_login @Action = 'update_one',
  37. @UserNamePattern = @UserName,
  38. @LoginName = @UserName;
  39. END
  40. ELSE
  41. BEGIN
  42. DECLARE @SQL NVARCHAR(200)
  43. SET @SQL = 'CREATE LOGIN ' + @UserName + ' WITH PASSWORD='''''
  44. EXEC(@SQL)
  45. EXEC sp_change_users_login @Action = 'update_one',
  46. @UserNamePattern = @UserName,
  47. @LoginName = @UserName;
  48. END
  49.  
  50. FETCH NEXT FROM Cur_OrphanedUsers INTO @UserName
  51. END
  52. CLOSE Cur_OrphanedUsers
  53. DEALLOCATE Cur_OrphanedUsers
  54.  
  55. DROP TABLE #OrphanedUser
  56. DROP TABLE #SqlLoginUser
  57. END
  58.  
  59. EXEC sp_fix_orphaned_users

场景2:可以登录原实例(使用系统SP或使用【0】中SQL)

  1. USE master
  2. GO
  3. IF OBJECT_ID ('sp_hexadecimal') IS NOT NULL
  4. DROP PROCEDURE sp_hexadecimal
  5. GO
  6. CREATE PROCEDURE sp_hexadecimal
  7. @binvalue varbinary(256),
  8. @hexvalue varchar (514) OUTPUT
  9. AS
  10. DECLARE @charvalue varchar (514)
  11. DECLARE @i int
  12. DECLARE @length int
  13. DECLARE @hexstring char(16)
  14. SELECT @charvalue = '0x'
  15. SELECT @i = 1
  16. SELECT @length = DATALENGTH (@binvalue)
  17. SELECT @hexstring = '0123456789ABCDEF'
  18. WHILE (@i <= @length)
  19. BEGIN
  20. DECLARE @tempint int
  21. DECLARE @firstint int
  22. DECLARE @secondint int
  23. SELECT @tempint = CONVERT(int, SUBSTRING(@binvalue,@i,1))
  24. SELECT @firstint = FLOOR(@tempint/16)
  25. SELECT @secondint = @tempint - (@firstint*16)
  26. SELECT @charvalue = @charvalue +
  27. SUBSTRING(@hexstring, @firstint+1, 1) +
  28. SUBSTRING(@hexstring, @secondint+1, 1)
  29. SELECT @i = @i + 1
  30. END
  31.  
  32. SELECT @hexvalue = @charvalue
  33. GO
  34.  
  35. IF OBJECT_ID ('sp_help_revlogin') IS NOT NULL
  36. DROP PROCEDURE sp_help_revlogin
  37. GO
  38. CREATE PROCEDURE sp_help_revlogin @login_name sysname = NULL AS
  39. DECLARE @name sysname
  40. DECLARE @type varchar (1)
  41. DECLARE @hasaccess int
  42. DECLARE @denylogin int
  43. DECLARE @is_disabled int
  44. DECLARE @PWD_varbinary varbinary (256)
  45. DECLARE @PWD_string varchar (514)
  46. DECLARE @SID_varbinary varbinary (85)
  47. DECLARE @SID_string varchar (514)
  48. DECLARE @tmpstr varchar (1024)
  49. DECLARE @is_policy_checked varchar (3)
  50. DECLARE @is_expiration_checked varchar (3)
  51.  
  52. DECLARE @defaultdb sysname
  53.  
  54. IF (@login_name IS NULL)
  55. DECLARE login_curs CURSOR FOR
  56.  
  57. SELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM
  58. sys.server_principals p LEFT JOIN sys.syslogins l
  59. ON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name <> 'sa'
  60. ELSE
  61. DECLARE login_curs CURSOR FOR
  62.  
  63. SELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM
  64. sys.server_principals p LEFT JOIN sys.syslogins l
  65. ON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name = @login_name
  66. OPEN login_curs
  67.  
  68. FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin
  69. IF (@@fetch_status = -1)
  70. BEGIN
  71. PRINT 'No login(s) found.'
  72. CLOSE login_curs
  73. DEALLOCATE login_curs
  74. RETURN -1
  75. END
  76. SET @tmpstr = '/* sp_help_revlogin script '
  77. PRINT @tmpstr
  78. SET @tmpstr = '** Generated ' + CONVERT (varchar, GETDATE()) + ' on ' + @@SERVERNAME + ' */'
  79. PRINT @tmpstr
  80. PRINT ''
  81. WHILE (@@fetch_status <> -1)
  82. BEGIN
  83. IF (@@fetch_status <> -2)
  84. BEGIN
  85. PRINT ''
  86. SET @tmpstr = '-- Login: ' + @name
  87. PRINT @tmpstr
  88. IF (@type IN ( 'G', 'U'))
  89. BEGIN -- NT authenticated account/group
  90.  
  91. SET @tmpstr = 'CREATE LOGIN ' + QUOTENAME( @name ) + ' FROM WINDOWS WITH DEFAULT_DATABASE = [' + @defaultdb + ']'
  92. END
  93. ELSE BEGIN -- SQL Server authentication
  94. -- obtain password and sid
  95. SET @PWD_varbinary = CAST( LOGINPROPERTY( @name, 'PasswordHash' ) AS varbinary (256) )
  96. EXEC sp_hexadecimal @PWD_varbinary, @PWD_string OUT
  97. EXEC sp_hexadecimal @SID_varbinary,@SID_string OUT
  98.  
  99. -- obtain password policy state
  100. SELECT @is_policy_checked = CASE is_policy_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = @name
  101. SELECT @is_expiration_checked = CASE is_expiration_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = @name
  102.  
  103. SET @tmpstr = 'CREATE LOGIN ' + QUOTENAME( @name ) + ' WITH PASSWORD = ' + @PWD_string + ' HASHED, SID = ' + @SID_string + ', DEFAULT_DATABASE = [' + @defaultdb + ']'
  104.  
  105. IF ( @is_policy_checked IS NOT NULL )
  106. BEGIN
  107. SET @tmpstr = @tmpstr + ', CHECK_POLICY = ' + @is_policy_checked
  108. END
  109. IF ( @is_expiration_checked IS NOT NULL )
  110. BEGIN
  111. SET @tmpstr = @tmpstr + ', CHECK_EXPIRATION = ' + @is_expiration_checked
  112. END
  113. END
  114. IF (@denylogin = 1)
  115. BEGIN -- login is denied access
  116. SET @tmpstr = @tmpstr + '; DENY CONNECT SQL TO ' + QUOTENAME( @name )
  117. END
  118. ELSE IF (@hasaccess = 0)
  119. BEGIN -- login exists but does not have access
  120. SET @tmpstr = @tmpstr + '; REVOKE CONNECT SQL TO ' + QUOTENAME( @name )
  121. END
  122. IF (@is_disabled = 1)
  123. BEGIN -- login is disabled
  124. SET @tmpstr = @tmpstr + '; ALTER LOGIN ' + QUOTENAME( @name ) + ' DISABLE'
  125. END
  126. PRINT @tmpstr
  127. END
  128.  
  129. FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin
  130. END
  131. CLOSE login_curs
  132. DEALLOCATE login_curs
  133. RETURN 0
  134. GO
  135.  
  136. exec sp_help_revlogin
  137. -- 然后复制出来运行的结果,到迁移的机器上运行即可
  138.  
  139. 结果如图:
      
  1.  
  1.  

单个玩家详情片,镜像后详情篇

  1. --=========================================
  2. --在镜像搭建后,在主库服务器上创建登录,并在数据库上建立对应用户,
  3. --数据库中用户被同步到镜像数据库中,但登录是实例级对象,无法同步,
  4. --因此需要手动同步登录到镜像实例上。
  5.  
  6. --当登录未同步到镜像实例上时,如果镜像发生故障转移,则应用程序
  7. --无法访问镜像数据库,镜像数据库上未与登录向管理的用户被称为
  8. --孤立用户
  9.  
  10. --=========================================
  11. --http://msdn.microsoft.com/zh-cn/library/ms174378.aspx
  12.  
  13. sp_change_users_login [ @Action = ] 'action'
  14. [ , [ @UserNamePattern = ] 'user' ]
  15. [ , [ @LoginName = ] 'login' ]
  16. [ , [ @Password = ] 'password' ]
  17. [;]
  18. --Auto_Fix
  19. --将当前数据库的sys.database_principals 系统目录视图中的用户项链接到同名的SQL Server 登录名。如果不存在同名的登录名,将会创建一个。检查Auto_Fix 语句的结果,确认实际链接是否正确。在对安全性较为敏感的情况下,要避免使用Auto_Fix
  20.  
  21. --如果使用Auto_Fix 时登录名尚不存在,则必须指定user password,否则必须指定user,但password 将被忽略。login 必须为NULLuser 必须是当前数据库中的有效用户。不能将另一个用户映射到该登录名。
  22.  
  23. --Report
  24. --列出当前数据库中未链接到任何登录名的用户以及相应的安全标识符(SID)。userlogin password 必须为NULL 或不指定。
  25.  
  26. --若要使用系统表通过某个查询替换报表选项,请将sys.server_prinicpals 中的条目与sys.database_principals 中的条目进行比较。
  27.  
  28. --Update_One
  29. --将当前数据库中指定的user 链接到现有的SQL Server login。必须指定user loginpassword 必须为NULL 或不指定。
  30.  
  31. --=========================================
  32. --镜像切换后
  33. --查看孤立用户
  34. USE REPDB
  35. GO
  36. EXEC sp_change_users_login
  37. @Action = 'REPORT',
  38. @UserNamePattern = NULL,
  39. @LoginName = NULL,
  40. @Password = NULL
  41.  
  42. --=========================================
  43. --创建登录[T1],并将T1和数据库[REPDB]中的用户[T1]关联
  44. --该方式同样导致镜像两段的登录SID不同,从而导致孤立用户
  45. USE [master]
  46. GO
  47. CREATE LOGIN [T1] WITH PASSWORD=N'T1', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
  48. GO
  49. USE REPDB
  50. GO
  51. EXEC sp_change_users_login
  52. @Action = 'Update_One',
  53. @UserNamePattern = 'T1',
  54. @LoginName = 'T1'
  55.  
  56. --=========================================
  57. --使用AUTO_FIX来解决
  58. --该方式同样导致镜像两段的登录SID不同,从而导致孤立用户
  59. USE REPDB
  60. GO
  61. EXEC sp_change_users_login
  62. @Action = 'Auto_Fix',
  63. @UserNamePattern = 'T2',
  64. @Password = 'T2'
  65.  
  66. --=========================================
  67. --推荐做法
  68. --在主库上查询得到需要同步的用户sid
  69. USE master;
  70. select sid,name from syslogins;
  71.  
  72. --============================================
  73. --在从库上创建登录
  74. exec sp_addlogin
  75. @loginame = 'DB1Login',
  76. @passwd = 'Sql@123',
  77. @sid=0x82873B5AFFEFE54EB4F9CA05C303C9AE

sql server中的孤立用户的更多相关文章

  1. SQL SERVER中用户定义标量函数(scalar user defined function)的性能问题

    用户定义函数(UDF)分类  SQL SERVER中的用户定义函数(User Defined Functions 简称UDF)分为标量函数(Scalar-Valued Function)和表值函数(T ...

  2. SQL Server中查询用户的对象权限和角色的方法

    --SQL Server中查询用户的对象权限和角色的方法 -- 查询用户的object权限 exec sp_helprotect NULL, 'sa' -- 查询用户拥有的role exec sp_h ...

  3. 此操作只能由 SQL Server 中拥有配置数据库读取权限的用户在已加入到某个服务器场的计算机上执行

    错误提示:此操作只能由 SQL Server 中拥有配置数据库读取权限的用户在已加入到某个服务器场的计算机上执行.若要将此服务器连接到服务器场,请使用 SharePoint 产品配置向导,该向导可从 ...

  4. SQL Server中授予用户查看对象定义的权限

    SQL Server中授予用户查看对象定义的权限   在SQL Server中,有时候需要给一些登录名(用户)授予查看所有或部分对象(存储过程.函数.视图.表)的定义权限存.如果是部分存储过程.函数. ...

  5. SQL Server中模式(schema)、数据库(database)、表(table)、用户(user)之间的关系

    数据库的初学者往往会对关系型数据库模式(schema).数据库(database).表(table).用户(user)之间感到迷惘,总感觉他们的关系千丝万缕,但又不知道他们的联系和区别在哪里,对一些问 ...

  6. SQL还原数据库后孤立用户问题处理(SQL 数据库 拥有对象 无法删除)

    所谓孤立帐户,就是某个数据库的帐户只有用户名而没有登录名,这样的用户在用户库的sysusers系统表中存在,而在master数据库的syslogins中却没有对应的记录 孤立帐户的产生一般是一下两种: ...

  7. SQL Server中约束的介绍

    SQL Server中约束的介绍(转载收藏) Posted on 2010-09-03 11:05 grayboy 阅读(8501) 评论(0) 编辑 收藏 作者:GrayBoy 出处:http:// ...

  8. Microsoft SQL Server中的事务与并发详解

    本篇索引: 1.事务 2.锁定和阻塞 3.隔离级别 4.死锁 一.事务 1.1 事务的概念 事务是作为单个工作单元而执行的一系列操作,比如查询和修改数据等. 事务是数据库并发控制的基本单位,一条或者一 ...

  9. sql server中对xml进行操作

    一.前言 SQL Server 2005 引入了一种称为 XML 的本机数据类型.用户可以创建这样的表,它在关系列之外还有一个或多个 XML 类型的列:此外,还允许带有变量和参数.为了更好地支持 XM ...

随机推荐

  1. Java反射机制在工厂模式中的应用

    在本篇文章中就不详细介绍工厂模式,主要介绍一下反射在工厂模式中的使用,让读者对反射机制带来的好处有更深的认识. 首先看一下简单工厂模式 简单工厂模式(simple factory)是类的创建模式,又叫 ...

  2. jquery设置radio选中

    <script type="text/javascript"> $(document).ready(function(){ $("input[type=rad ...

  3. android4.0.3源码之USB wifi移植心得

    http://blog.csdn.net/eastmoon502136/article/details/7850157 http://forum.cubietech.com/forum.php?mod ...

  4. 对于try catch放在能够很好地处理例外的位置

    Exception有一个message属性.在使用catch的时候可以调用: Catch(IOException e){System.out.println(e.message())}; Catch( ...

  5. Struts2的拦截器是如何使用AOP工作的

    拦截器(interceptor)是Struts2最强大的特性之一,也可以说是struts2的核心,拦截器可以让你在Action和result被执行之前或之后进行一些处理.同时,拦截器也可以让你将通用的 ...

  6. linux下面bin,sbin不理解的查阅

    在一下的文件中得到答案, 突然想想自己有点傻,自己有代码,为什么不自己查看一下代码呢 http://blog.csdn.net/ithomer/article/details/9839957

  7. jQuery监控文本框事件并作相应处理的方法

    本文实例讲述了jQuery监控文本框事件并作相应处理的方法.分享给大家供大家参考.具体如下: //事情委托 $(document)  .on('input propertychange', '#que ...

  8. systemd新的系统管理方案

    http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html http://www.ruanyifeng.com/blog ...

  9. HDU 5900 QSC and Master

    题目链接:传送门 题目大意:长度为n的key数组与value数组,若相邻的key互斥,则可以删去这两个数同时获得对应的两 个value值,问最多能获得多少 题目思路:区间DP 闲谈: 这个题一开始没有 ...

  10. 【黑金原创教程】【Modelsim】【第六章】结束就是开始

    声明:本文为黑金动力社区(http://www.heijin.org)原创教程,如需转载请注明出处,谢谢! 黑金动力社区2013年原创教程连载计划: http://www.cnblogs.com/al ...