SQL Server 中登录账号与数据库用户迁移

1.      先创建一个SqlServer
身份验证的登录名,并映射到数据库中。

如:创建用户 [kk] 映射到数据库 [mytest],此时数据库 [mytest]
会增加一个用户 [kk]

2.      此时再删除登录名 [kk],删除后,数据库[mytest]
将存在一个孤立用户 [kk]

3.      查看当前数据库中是否存在孤立用户

use mytest;
exec sp_change_users_login @Action='Report';

4.      对于孤立用户,有两种情况:

a 不知道这些数据库用户之前的登录名或记不清楚数据库来源

b 对于数据库迁移一种情况,先迁移数据库,再迁移登录账号

第一种情况:

--	创建登录名
use master;
create login [kk] with password = '123456';
go

--	对孤立用户连接到现有的登录名
use mytest;
exec sp_change_users_login
	@action='update_one',
	@usernamepattern='kk', --数据库孤立用户
	@loginname='kk'; --关联到sql server登录名
go

--	也可以再次修改密码
use master
go
sp_password @old=null, @new='654321', @loginame='kk';
go

第二种情况:参考 如何在 SQL Server 2005 实例之间传输登录和密码

如:要创建与另一个数据库结构一样的数据库,可以导出脚本到另一台服务器中执行(其中有数据库用户)

注意:数据库用户的权限并没有随之授予,须手动再次授予权限!

在原数据库中创建存储过程:

USE master
GO
IF OBJECT_ID ('sp_hexadecimal') IS NOT NULL
  DROP PROCEDURE sp_hexadecimal
GO
CREATE PROCEDURE sp_hexadecimal
    @binvalue varbinary(256),
    @hexvalue varchar (514) OUTPUT
AS
DECLARE @charvalue varchar (514)
DECLARE @i int
DECLARE @length int
DECLARE @hexstring char(16)
SELECT @charvalue = '0x'
SELECT @i = 1
SELECT @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 + 1
END

SELECT @hexvalue = @charvalue
GO

IF OBJECT_ID ('sp_help_revlogin') IS NOT NULL
  DROP PROCEDURE sp_help_revlogin
GO
CREATE PROCEDURE sp_help_revlogin @login_name sysname = NULL AS
DECLARE @name sysname
DECLARE @type varchar (1)
DECLARE @hasaccess int
DECLARE @denylogin int
DECLARE @is_disabled int
DECLARE @PWD_varbinary  varbinary (256)
DECLARE @PWD_string  varchar (514)
DECLARE @SID_varbinary varbinary (85)
DECLARE @SID_string varchar (514)
DECLARE @tmpstr  varchar (1024)
DECLARE @is_policy_checked varchar (3)
DECLARE @is_expiration_checked varchar (3)

DECLARE @defaultdb sysname

IF (@login_name IS NULL)
  DECLARE login_curs CURSOR FOR

      SELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM
sys.server_principals p LEFT JOIN sys.syslogins l
      ON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name <> 'sa'
ELSE
  DECLARE login_curs CURSOR FOR

      SELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM
sys.server_principals p LEFT JOIN sys.syslogins l
      ON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name = @login_name
OPEN login_curs

FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin
IF (@@fetch_status = -1)
BEGIN
  PRINT 'No login(s) found.'
  CLOSE login_curs
  DEALLOCATE login_curs
  RETURN -1
END
SET @tmpstr = '/* sp_help_revlogin script '
PRINT @tmpstr
SET @tmpstr = '** Generated ' + CONVERT (varchar, GETDATE()) + ' on ' + @@SERVERNAME + ' */'
PRINT @tmpstr
PRINT ''
WHILE (@@fetch_status <> -1)
BEGIN
  IF (@@fetch_status <> -2)
  BEGIN
    PRINT ''
    SET @tmpstr = '-- Login: ' + @name
    PRINT @tmpstr
    IF (@type IN ( 'G', 'U'))
    BEGIN -- NT authenticated account/group

      SET @tmpstr = 'CREATE LOGIN ' + QUOTENAME( @name ) + ' FROM WINDOWS WITH DEFAULT_DATABASE = [' + @defaultdb + ']'
    END
    ELSE BEGIN -- SQL Server authentication
        -- obtain password and sid
            SET @PWD_varbinary = CAST( LOGINPROPERTY( @name, 'PasswordHash' ) AS varbinary (256) )
        EXEC sp_hexadecimal @PWD_varbinary, @PWD_string OUT
        EXEC sp_hexadecimal @SID_varbinary,@SID_string OUT

        -- obtain password policy state
        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
        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

            SET @tmpstr = 'CREATE LOGIN ' + QUOTENAME( @name ) + ' WITH PASSWORD = ' + @PWD_string + ' HASHED, SID = ' + @SID_string + ', DEFAULT_DATABASE = [' + @defaultdb + ']'

        IF ( @is_policy_checked IS NOT NULL )
        BEGIN
          SET @tmpstr = @tmpstr + ', CHECK_POLICY = ' + @is_policy_checked
        END
        IF ( @is_expiration_checked IS NOT NULL )
        BEGIN
          SET @tmpstr = @tmpstr + ', CHECK_EXPIRATION = ' + @is_expiration_checked
        END
    END
    IF (@denylogin = 1)
    BEGIN -- login is denied access
      SET @tmpstr = @tmpstr + '; DENY CONNECT SQL TO ' + QUOTENAME( @name )
    END
    ELSE IF (@hasaccess = 0)
    BEGIN -- login exists but does not have access
      SET @tmpstr = @tmpstr + '; REVOKE CONNECT SQL TO ' + QUOTENAME( @name )
    END
    IF (@is_disabled = 1)
    BEGIN -- login is disabled
      SET @tmpstr = @tmpstr + '; ALTER LOGIN ' + QUOTENAME( @name ) + ' DISABLE'
    END
    PRINT @tmpstr
  END

  FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin
   END
CLOSE login_curs
DEALLOCATE login_curs
RETURN 0
GO

执行存储过程,将生成登录名的创建脚本

EXEC sp_help_revlogin

将脚本拷贝到当前数据库孤立用户的服务器中执行(更多注意问题参考
如何在 SQL Server 2005 实例之间传输登录和密码

CREATE LOGIN [kk]
WITH
PASSWORD = 0x0100FDBC7416947C56E903E945B5DF891643064BB7D16381577F HASHED,
SID = 0xAE142AE3C75E9341B106B9BAA60BB0CC,
DEFAULT_DATABASE = [mytest],
CHECK_POLICY = OFF,
CHECK_EXPIRATION = OFF

虽然登录名和数据库用户已经存在了,但是原来数据库用户的角色身份、对象权限都没有了!

这时,在原数据库执行以下脚本,拷贝脚本到新的数据库中执行,将权限还原

(授予数据库孤立用户权限或者其他所有用户的权限都“迁移”过来)

--	更改【此用户拥有的架构】
select s.name,p.name,'ALTER AUTHORIZATION ON SCHEMA::['+s.name+'] TO ['+p.name+']'
from sys.schemas s inner join sys.database_principals p on s.principal_id=p.principal_id
where s.name <> p.name

--	授予【数据库角色成员身份】权限
SELECT 'exec sp_addrolemember N'''+g.name+''', N'''+u.name+''''
FROM sys.database_principals u
inner join sys.database_role_members m on u.principal_id = m.member_principal_id
inner join sys.database_principals g on g.principal_id = m.role_principal_id
ORDER BY g.name,u.name

--	授予【安全对象】权限
SELECT N'grant '+B.permission_name  collate chinese_prc_ci_ai_ws+N' on ['+A.name+N'] to ['+C.name+N']'
FROM sys.sysobjects A(NOLOCK)
INNER JOIN sys.database_permissions B(NOLOCK) ON A.id=B.major_id
INNER JOIN sys.database_principals C(NOLOCK) ON B.grantee_principal_id=C.principal_id
--WHERE C.name='kk' --A.name='objectName'

如果【数据库用户】还有对其他对象有操作权限,另外授予(当前不列出所有权限)

至此,完成账号迁移,步骤如下:

1 数据库迁移,产生孤立用户

2 登录账号迁移,关联孤立用户

3 数据库用户权限迁移,所有操作权限重新授予

参考:

如何在
SQL Server 2005
实例之间传输登录和密码

孤立用户故障排除(SQL
Server)

时间: 2024-11-08 19:09:11

SQL Server 中登录账号与数据库用户迁移的相关文章

SQL Server客户端登录名与数据库用户关联

数据库迁移之后,在新的SQL Server客户端工具设置关联时,往往会报错: 用户.组或角色 'XXX' 在当前数据库中已存在. 解决方法: 首先介绍一下sql server中“登录”与“用户”的区别,“登录”用于用户身份验证,而数据库“用户”帐户用于数据库访问和权限验证.登录通过安全识别符 (SID) 与用户关联. 将数据库恢复到其他服务器时,数据库中包含一组用户和权限,但此时数据库服务器没有与这一组用户关联的登录名.这种情况被称为存在“孤立用户”.此时不能通过新建登录或者是对同名登录授予对应

Sql Server中判断表或者数据库是否存在

Sql Server中判断表或者数据库是否存在 SQL Server中判断数据库是否存在: 法(一): select * From master.dbo.sysdatabases where name='数据库名' 法(二): if db_id('数据库名') is not null drop database ... go create ... SQL Server中判断表对象是否存在: select count(*) from sysobjects where id = object_id(

转:SQL Server中服务器角色和数据库角色权限详解

当几个用户需要在某个特定的数据库中执行类似的动作时(这里没有相应的Windows用户组),就可以向该数据库中添加一个角色(role).数据库角色指定了可以访问相同数据库对象的一组数据库用户. 数据库角色的成员可以分为如下几类: Windows用户组或用户账户 SQL Server登录 其他角色 SQL Server的安全体系结构中包括了几个含有特定隐含权限的角色.除了数据库拥有者创建的角色之外,还有两类预定义的角色.这些可以创建的角色可以分为如下几类: 固定服务器 固定数据库 用户自定义 固定服

SQL Server中服务器身份验证及用户登录

安装过程中,SQL Server 数据库引擎设置为"Windows 身份验证模式"或"SQL Server 和 Windows 身份验证模式". 安装完成后,您可以随时更改身份验证模式. 如果在安装过程中选择了"Windows 身份验证模式",则 sa 登录名将被禁用,安装程序会分配一个密码. 如果稍后将身份验证模式更改为"SQL Server 和 Windows 身份验证模式",则 sa 登录名仍处于禁用状态. 若要使用 s

SQl Server 中登录名 、用户、角色、概念一览

转载:http://www.2cto.com/database/201306/216922.html 数据库,角色,用户,安全 登录SQL server 2008可以用windows身份验证也可以用sql server身份验证,不论那种,进入数据库后 都拥有超级用户的权限,这显然是不太安全的.合理的做法是:对于一个数据库,应该是由不同权限的用户 进行操作和管理. 本博文将结合一个例子来讲解如何建立数据库,并为数据库建立不同权限的用户. 一.登录数据库管理系统(首先要打开SQL Server数据库

SQL Server 忘记登录账号解决方法

[1] 停止SQL Server 服务 和 SQL Server Agent 服务 [2] 以管理员身份打开命令行,单用户模式启动服务.(在单用户模式下启动 SQL Server 可使计算机本地 Administrators 组的任何成员作为 sysadmin 固定服务器角色的成员连接到 SQL Server 实例)C:\Windows\system32>net start MSSQLSERVER /mSQL Server (MSSQLSERVER) 服务正在启动 .SQL Server (MS

sql server 中隐藏掉无关数据库

先贴上我实际测试的效果 Problem I have a SQL Server instance that has hundreds of databases.  Navigating the database tree in SSMS is a pain and I was wondering if there was a way to limit the list of databases that I see in SSMS? Solution SQL Server consolidati

SQL Server 2008 错误15023:当前数据库中已存在用户或角色

解决SQL Server 2008 错误15023:当前数据库中已存在用户或角色,SQLServer2008,错误15023,在使用SQL Server 2008时,我们经常会遇到一个情况:需要把一台服务器上的数据库转移到另外一台服务器上.而转移完成后,需要给一个"登录"关联一个"用户"时,往往会发生错误:      “错误15023:当前数据库中已存在用户或角色”        这个问题非常棘手,几经排常找到了原因与解决方法,因为这个问题与解决方法均比较复杂,所以

将SQL Server中的数据库导入到PowerDesigner

再用PD建表完成后导成SQL脚本然后在SQL Server中运行后生成数据库后,就想到,可不可以将直接将数据库的内容生成PD文档?经过上网查,当然可以的. 要将SQL Server中的数据库导入到PD中,首先需要建立一个数据库的链接,然后进行逆向工程的操作.下面开始操作. 第一步:打开数据库菜单,选择"Configure Connections" 第二步:创建新的ODBC链接 第三步:选择系统数据源 第四步:选择需要的数据库 第五步:"完成" 第六步:命名数据源,并