SQL Server 服务器器信息备份(一)--login新建脚本备份

前言

若你的企业使用SQL Server数据库镜像为容灾技术。

那你一定做过在镜像切换之前要新建Login,而且若Login密码不同,要修改链接数据库的字符串,在切换完之后则仍需要给数据库重新赋予权限。

若真的是这样做,不仅麻烦而且业务故障时间将会拉长,我们需要做到新建的Login与之前的密码完全一样,而且可自动根据原有数据库用户链接到Login,数据库级别权限不用从新处理。

思路

有了这样的思路则Login的信息备份需要考虑两点:

1、一定要获取用户的SID,以保证镜像切换后能自动连接到login。

2、如何将二进制类型的用户密码和SID转换成字符类型存放

    数据库存一个二进制为8Bit,每四位为一个16进制。8Bit二进制除以16则取得高4Bit的二进制,模以16则取低4Bit二进制。如下所示

Substring('0123456789ABCDEF',8bit / 16 + 1,1) + Substring('0123456789ABCDEF',8bit % 16 + 1,1)

脚本

通过以上想法笔者得出以下脚本:

脚本通过循环处理分析二进制的SID和PASSWORD得到相应的字符串,拼成相应login 的新建脚本,将脚本存放到指定文件下。

  1 CREATE PROC  [dbo].[spm_GetLoginDetails] 
  2     @loginame varchar(100)=null,
  3     @filepath varchar(1000)=null
  4 AS
  5     SET NOCOUNT ON
  6 
  7     DECLARE @bin_pwd VARBINARY (8000)
  8     DECLARE @bin_sid VARBINARY (8000)--VARBINARY密码和sid
  9     DECLARE @string_pwd VARCHAR(8000) 
 10     SET @string_pwd=''
 11     DECLARE @string_sid VARCHAR(8000) 
 12     SET @string_sid=''
 13 
 14     DECLARE @pwd INT,@sid INT
 15     /*脚本存放*/
 16     CREATE TABLE ##scriptall(id INT IDENTITY(1,1),line VARCHAR(MAX))
 17 
 18     /*如果loginame 不存在则输出所有脚本*/
 19     IF @loginame IS NULL 
 20     BEGIN
 21      CREATE TABLE #temp(id INT IDENTITY(1,1),name VARCHAR(100),sid VARBINARY(256),string_pwd VARCHAR(1000),string_sid VARCHAR(1000))
 22  
 23      INSERT INTO #temp(sid,name)
 24      SELECT sid,name FROM   sys.sql_logins
 25  
 26      DECLARE @minid INT,@maxid INT
 27      SELECT @minid=min(id),@maxid=MAX(id) FROM #temp
 28 
 29      /*VARBINARY类型转化处理*/
 30      WHILE (@minid<=@maxid)
 31       BEGIN 
 32             SELECT @bin_pwd = sl.password_hash,@bin_sid=sl.sid,@string_pwd='',@string_sid=''
 33             FROM   sys.sql_logins sl join #temp t on t.sid =sl.sid 
 34             where t.id=@minid
 35 
 36             /*密码类型转化*/ 
 37             SELECT  @pwd = Datalength(@bin_pwd),@sid=Datalength(@bin_sid)
 38             WHILE @pwd > 0
 39               BEGIN
 40                 SELECT @string_pwd = Substring('0123456789ABCDEF',Substring(@bin_pwd,@pwd,1) / 16 + 1,1) + 
 41                                      Substring('0123456789ABCDEF',Substring(@bin_pwd,@pwd,1)%16 + 1,1) + @string_pwd
 42                                      ,@pwd = @pwd - 1
 43               END
 44             SELECT @string_pwd = ('0x' + @string_pwd)
 45 
 46            /*sid类型转化*/ 
 47             WHILE @sid > 0
 48               BEGIN
 49                 SELECT @string_sid = Substring('0123456789ABCDEF',Substring(@bin_sid,@sid,1) / 16 + 1,1) + 
 50                                      Substring('0123456789ABCDEF',Substring(@bin_sid,@sid,1)%16 + 1,1) + @string_sid,
 51                                      @sid = @sid - 1
 52               END          
 53             SELECT @string_sid = ('0x' + @string_sid)
 54             UPDATE #temp SET string_pwd=@string_pwd,string_sid=@string_sid WHERE id=@minid        
 55             SET @minid=@minid+1        
 56       END
 57      /*导出login新建脚本*/
 58      INSERT INTO  ##scriptall(line)
 59      SELECT CASE WHEN sp.TYPE = 'S' THEN '
 60      /****** Object:  Login ['+sp.name+']    Script Date: '+convert(VARCHAR,GETDATE(),25)+' ******/
 61      CREATE LOGIN [' + sp.name + '] WITH PASSWORD = ' + t.string_pwd + '  HASHED, SID = ' + t.string_sid + ',CHECK_POLICY = ' + CASE sl.is_policy_checked WHEN 0 THEN 'OFF'ELSE 'ON'END + '  , CHECK_EXPIRATION = ' + CASE sl.is_policy_checked WHEN 0 THEN 'OFF'ELSE 'ON'END +char(10)+CASE when s.denylogin=1 then '; DENY CONNECT SQL TO ' + QUOTENAME( sp.name ) else '' end +case when  s.hasaccess=0 then '; REVOKE CONNECT SQL TO ' + QUOTENAME( sp.name )  else ''end  
 62      ELSE 
 63      '/****** Object:  Login ['+sp.name+']    Script Date: '+convert(VARCHAR,GETDATE(),25)+' ******/
 64      CREATE LOGIN [' + sp.name + '] FROM WINDOWS WITH DEFAULT_DATABASE=[' + sp.default_database_name + ']'
 65      END 
 66       FROM   sys.sql_logins sl
 67                RIGHT JOIN sys.server_principals sp
 68                  ON sl.sid = sp.sid
 69                JOIN sys.syslogins s
 70                  ON s.sid = sp.sid
 71                left join #temp t on t.sid=sl.sid
 72       WHERE  sp.TYPE IN ('S','G','U') and loginname<>'sa'
 73       ORDER BY sp.name
 74     END
 75     /*若存在loginame,则输出相应的脚本*/
 76     ELSE 
 77     BEGIN 
 78 
 79     IF EXISTS (SELECT TOP 1 1 FROM   sys.sql_logins s  WHERE  s.name = @loginame)
 80       BEGIN
 81     
 82         SELECT @bin_pwd = sl.password_hash,@bin_sid=sl.sid
 83         FROM   sys.sql_logins sl
 84         WHERE  sl.name = @loginame
 85         SELECT  @pwd = Datalength(@bin_pwd),@sid=Datalength(@bin_sid)
 86         /*密码类型转化*/ 
 87         WHILE @pwd > 0
 88           BEGIN
 89             SELECT @string_pwd = Substring('0123456789ABCDEF',Substring(@bin_pwd,@pwd,1) / 16 + 1,
 90                                    1) + Substring('0123456789ABCDEF',Substring(@bin_pwd,@pwd,1)%16 + 1,
 91                                                   1) + @string_pwd,@pwd = @pwd - 1              
 92           END
 93         SELECT @string_pwd = ('0x' + @string_pwd)
 94         /*SID类型转化*/ 
 95         WHILE @sid > 0
 96           BEGIN
 97             SELECT @string_sid = Substring('0123456789ABCDEF',Substring(@bin_sid,@sid,1) / 16 + 1,
 98                                    1) + Substring('0123456789ABCDEF',Substring(@bin_sid,@sid,1)%16 + 1,
 99                                                   1) + @string_sid,@sid = @sid - 1
100                
101           END
102         SELECT @string_sid = ('0x' + @string_sid)
103     
104       END
105      /*导出login新建脚本*/
106      INSERT INTO ##scriptall(line)
107      SELECT CASE WHEN sp.TYPE = 'S' THEN '
108      /****** Object:  Login ['+sp.name+']    Script Date: '+convert(varchar,GETDATE(),25)+' ******/
109      CREATE LOGIN [' + sp.name + '] WITH PASSWORD = ' + @string_pwd + '  HASHED, SID = ' + @string_sid + ',CHECK_POLICY = ' + CASE sl.is_policy_checked WHEN 0 THEN 'OFF'ELSE 'ON'END + '  , CHECK_EXPIRATION = ' + CASE sl.is_policy_checked WHEN 0 THEN 'OFF'ELSE 'ON'END +char(10)+CASE when s.denylogin=1 then '; DENY CONNECT SQL TO ' + QUOTENAME( sp.name ) else '' end +case when  s.hasaccess=0 then '; REVOKE CONNECT SQL TO ' + QUOTENAME( sp.name )  else ''end  
110      ELSE 
111      '/****** Object:  Login ['+sp.name+']    Script Date: '+convert(varchar,GETDATE(),25)+' ******/
112      CREATE LOGIN [' + sp.name + '] FROM WINDOWS WITH DEFAULT_DATABASE=[' + sp.default_database_name + ']'
113     END
114     FROM   sys.sql_logins sl
115            RIGHT JOIN sys.server_principals sp
116              ON sl.sid = sp.sid
117            JOIN sys.syslogins s
118              ON s.sid = sp.sid
119     WHERE  sp.TYPE IN ('S','G','U')
120            AND sp.name = @loginame
121     END
122 
123   /*结果集输出*/
124   IF @filepath IS NULL
125     BEGIN
126       SELECT   line
127       FROM     ##scriptall
128       ORDER BY id ASC
129       DROP TABLE ##scriptall
130     END
131   ELSE
132     BEGIN
133       declare @cmd varchar(1000)
134       SELECT @cmd = 'master..xp_cmdshell ''bcp "select line from  ##ScriptAll order by id" queryout ' + @filepath + ' -T -c -S' + @@SERVERNAME + ''''
135       EXEC( @cmd)
136       DROP TABLE ##scriptall
137     END
View Code

 

posted @ 2014-08-27 19:56  阿传说  阅读(527)  评论(0编辑  收藏  举报