日期:2014-05-16  浏览次数:20641 次

登录名和数据库用户无法映射,形成数据库孤立现象
  1. 当数据库从一个地方还原到另一个地方时会出现孤立用户问题。孤立用户简单来说就是在原来数据库上的用户到了新的数据库中就找不到登录用户了。即使你建一个一模一样的登录用户,也没法与旧的用户对应上,因为sqlserver中用户是通过SID去标识一个用户的,而不是用户名。这时如果你想删掉旧用户也是办不到的,因为旧用户会占有一些对象,例如表,存储过程等,这些东西令你无法删掉它。

???? ?(比如 系统表前面的dbo就是登陆用户) 你原来数据库的用户名是user1 在企业管理器里 旧数据库里表名显示的是 user1.表名 你还原到新数据库的时候 表名还是这样 但是你的新登陆用户名并不是这个了我用官方的帮助文档里执行这个查询可是不成功 也不知道为什么

?

?

???? 官方文档的帮助
???? 我有自己的服务器,我将SQLServer数据库备份后,我重新安装了SQLServer并将备份数据库还原,但论坛运行后提示表不存在。
??????Discuz!NT SQLServer版的用户可能会遇到这个问题, 下面就详细的解释下问题的原因和解决办法。
???

??????例如:新建数据库discuz,新建一个用户user1,指定user1对数据库discuz有权限,然后安装Discuz!NT SQLServer版,Discuz!NT的安装程序自动为用户创建表,此时discuz中的表的所有者就是user1,这样的好处是不需要user1用户拥有任何sqlserver权限身份,安全性高(有的用户用sa或其它管理员帐号来运行论坛,本地测试当然是无所谓,但如果是在服务器上这么做,一旦被恶意利用,可能就要威胁到所有数据库甚至整个服务器的系统!还有一些程序没有安装程序,只是提供SQL脚本让用户创建表,很多用户就用管理员帐号来创建了表,那时表的所有者为dbo,因此一般不出现该问题)。后来备份数据库并重新安装SQLServer,再将备份的数据库还原,discuz数据库的所有者还是user1,但user1不存在,你新指定的用户user2可能也无法再操作discuz数据库。虽然你看到表并没有缺少,但user2却无权访问到它们,因此可能会提示表不存在。

?

??????解决这个问题的办法很简单:假设你的数据库叫discuz,原来的所有者是用户user1,备份还原后你新建立了一个用户user2,遇到上述问题后,以管理员身份进入查询分析器,选择数据库discuz,执行以下SQL命令:

?

????? EXEC sp_change_users_login update_one, 'user1', 'user2'

??????执行完毕后,user2即对discuz数据库拥有权限。另外特别需要提醒的是:当你修改了数据库帐号后,请将论坛dnt.config中的小节里面帐号信息也做相应的修改,然后重新启动IIS里的应用程序池。

?

???? 于是我只能另外在网上想办法解决 终于找到了这个解决方法 先在要操作的数据库中建立如下存储过程,代码如下:

  1. Create PROCEDURE ChangeAllObjOwner (
  2. @oldowner sysname,
  3. @newowner sysname
  4. )
  5. AS
  6. DECLARE @objname sysname
  7. SET NOCOUNT ON
  8. --检查旧用户是否存在
  9. IF USER_ID(@oldowner) IS NULL
  10. BEGIN
  11. RAISERROR ('The @oldowner passed does not exist in the database', 16, 1)
  12. RETURN
  13. END
  14. --检查新用户是否存在
  15. IF USER_ID(@newowner) IS NULL
  16. BEGIN
  17. RAISERROR ('The @newowner passed does not exist in the database', 16, 1)
  18. RETURN
  19. END
  20. DECLARE owner_cursor CURSOR FOR
  21. Select name FROM sysobjects Where uid = USER_ID(@oldowner)
  22. OPEN owner_cursor
  23. FETCH NEXT FROM owner_cursor INTO @objname
  24. WHILE (@@fetch_status <> -1)
  25. BEGIN
  26. SET @objname = @oldowner + '.' + @objname
  27. EXEC sp_changeobjectowner @objname, @newowner
  28. FETCH NEXT FROM owner_cursor INTO @objname
  29. END
  30. CLOSE owner_cursor
  31. DEALLOCATE owner_cursor
  32. GO

????????? 存储过程建立后我用下面的方法完成了最后的步骤在企业管理器里新建查询对所在数据库执行下面的语句(假设旧数据库用户是user1 新数据库是user2)

?

???????? exec ChangeAllObjOwner 'user1','dbo'

?

???????? 把对象都转成是dbo的,也就是sa帐号下的,这时候就可以删除旧用户user1了然后执行

?

?

???????? exec ChangeAllObjOwner 'dbo','user2'

?