码迷,mamicode.com
首页 > 数据库 > 详细

知方可补不足~SQL数据库用户的克隆,SQL集群的用户同步问题

时间:2015-05-28 09:22:55      阅读:241      评论:0      收藏:0      [点我收藏+]

标签:

我们知道在为sqlserver建立功能数据库时,通过会为库再建立一个登陆名,而这个登陆名时,只用来管理这个数据库,这是安全的,正确的。

技术分享

我们在建立一个用户时,通过会把指定的数据库添加到“用户映射”里,这时你的用户与数据库就有了关系,在使用用户登陆时,你只能看到与该用户有映射关系的数据库!

技术分享

在SQL的集群环境下,假设你有两台服务器,它们之间建立集群,这时,你希望把A服务器的数据库用户同步到B服务器上,你当然可以手动在B上建立一个SQL用户,但这时,你也必须重新建立一个数据库的映射关系,因为这时用户名的SID已经不同了,如果希望在建立用户时同时绑定之前的数据库映射,我们需要使用下载的语句实现

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

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 @Principal_id int
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
DECLARE @language sysname
DECLARE @rolename sysname
DECLARE login_curs CURSOR FOR SELECT 
p.principal_id,
p.sid, 
p.name, 
p.type, 
p.is_disabled, 
p.default_database_name, 
p.default_language_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

OPEN login_curs

FETCH NEXT FROM login_curs INTO @Principal_id, @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @language, @hasaccess, @denylogin
IF (@@fetch_status = -1)
BEGIN
  PRINT No login(s) found.
  CLOSE login_curs
  DEALLOCATE login_curs
  RETURN
END
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 + ], DEFAULT_LANGUAGE = [ + @language + ]
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 + ], DEFAULT_LANGUAGE = [ + @language + ]

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
PRINT GO
DECLARE server_role_members_curs CURSOR FOR 
SELECT 
(SELECT [name] FROM sys.server_principals WHERE principal_id = role_principal_id) AS rolename
FROM 
sys.server_role_members 
WHERE 
member_principal_id = @Principal_id
OPEN server_role_members_curs

FETCH NEXT FROM server_role_members_curs INTO @rolename
WHILE (@@fetch_status <> -1)
BEGIN
SELECT @tmpstr = EXEC master..sp_addsrvrolemember @loginame = N‘‘‘ + @name + ‘‘‘, @rolename = N‘‘‘ + @rolename + ‘‘‘‘
PRINT @tmpstr
PRINT GO
FETCH NEXT FROM server_role_members_curs INTO @rolename
END
CLOSE server_role_members_curs
DEALLOCATE server_role_members_curs    
END
FETCH NEXT FROM login_curs INTO @Principal_id, @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @language, @hasaccess, @denylogin
END
CLOSE login_curs
DEALLOCATE login_curs
GO

DROP PROCEDURE #sp_hexadecimal
GO

运行的结果可能是这样的

技术分享

然后我们把希望同步的用户登陆名复制到B服务器,运行脚本,即可完成同步!

 

知方可补不足~SQL数据库用户的克隆,SQL集群的用户同步问题

标签:

原文地址:http://www.cnblogs.com/lori/p/4534968.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!