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 的新建脚本,将脚本存放到指定文件下。
CREATE PROC [dbo].[spm_GetLoginDetails]
@loginame varchar(100)=null,
@filepath varchar(1000)=null
AS
SET NOCOUNT ON DECLARE @bin_pwd VARBINARY (8000)
DECLARE @bin_sid VARBINARY (8000)--VARBINARY密码和sid
DECLARE @string_pwd VARCHAR(8000)
SET @string_pwd=''
DECLARE @string_sid VARCHAR(8000)
SET @string_sid='' DECLARE @pwd INT,@sid INT
/*脚本存放*/
CREATE TABLE ##scriptall(id INT IDENTITY(1,1),line VARCHAR(MAX)) /*如果loginame 不存在则输出所有脚本*/
IF @loginame IS NULL
BEGIN
CREATE TABLE #temp(id INT IDENTITY(1,1),name VARCHAR(100),sid VARBINARY(256),string_pwd VARCHAR(1000),string_sid VARCHAR(1000)) INSERT INTO #temp(sid,name)
SELECT sid,name FROM sys.sql_logins DECLARE @minid INT,@maxid INT
SELECT @minid=min(id),@maxid=MAX(id) FROM #temp /*VARBINARY类型转化处理*/
WHILE (@minid<=@maxid)
BEGIN
SELECT @bin_pwd = sl.password_hash,@bin_sid=sl.sid,@string_pwd='',@string_sid=''
FROM sys.sql_logins sl join #temp t on t.sid =sl.sid
where t.id=@minid /*密码类型转化*/
SELECT @pwd = Datalength(@bin_pwd),@sid=Datalength(@bin_sid)
WHILE @pwd > 0
BEGIN
SELECT @string_pwd = Substring('0123456789ABCDEF',Substring(@bin_pwd,@pwd,1) / 16 + 1,1) +
Substring('0123456789ABCDEF',Substring(@bin_pwd,@pwd,1)%16 + 1,1) + @string_pwd
,@pwd = @pwd - 1
END
SELECT @string_pwd = ('0x' + @string_pwd) /*sid类型转化*/
WHILE @sid > 0
BEGIN
SELECT @string_sid = Substring('0123456789ABCDEF',Substring(@bin_sid,@sid,1) / 16 + 1,1) +
Substring('0123456789ABCDEF',Substring(@bin_sid,@sid,1)%16 + 1,1) + @string_sid,
@sid = @sid - 1
END
SELECT @string_sid = ('0x' + @string_sid)
UPDATE #temp SET string_pwd=@string_pwd,string_sid=@string_sid WHERE id=@minid
SET @minid=@minid+1
END
/*导出login新建脚本*/
INSERT INTO ##scriptall(line)
SELECT CASE WHEN sp.TYPE = 'S' THEN '
/****** Object: Login ['+sp.name+'] Script Date: '+convert(VARCHAR,GETDATE(),25)+' ******/
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
ELSE
'/****** Object: Login ['+sp.name+'] Script Date: '+convert(VARCHAR,GETDATE(),25)+' ******/
CREATE LOGIN [' + sp.name + '] FROM WINDOWS WITH DEFAULT_DATABASE=[' + sp.default_database_name + ']'
END
FROM sys.sql_logins sl
RIGHT JOIN sys.server_principals sp
ON sl.sid = sp.sid
JOIN sys.syslogins s
ON s.sid = sp.sid
left join #temp t on t.sid=sl.sid
WHERE sp.TYPE IN ('S','G','U') and loginname<>'sa'
ORDER BY sp.name
END
/*若存在loginame,则输出相应的脚本*/
ELSE
BEGIN IF EXISTS (SELECT TOP 1 1 FROM sys.sql_logins s WHERE s.name = @loginame)
BEGIN SELECT @bin_pwd = sl.password_hash,@bin_sid=sl.sid
FROM sys.sql_logins sl
WHERE sl.name = @loginame
SELECT @pwd = Datalength(@bin_pwd),@sid=Datalength(@bin_sid)
/*密码类型转化*/
WHILE @pwd > 0
BEGIN
SELECT @string_pwd = Substring('0123456789ABCDEF',Substring(@bin_pwd,@pwd,1) / 16 + 1,
1) + Substring('0123456789ABCDEF',Substring(@bin_pwd,@pwd,1)%16 + 1,
1) + @string_pwd,@pwd = @pwd - 1
END
SELECT @string_pwd = ('0x' + @string_pwd)
/*SID类型转化*/
WHILE @sid > 0
BEGIN
SELECT @string_sid = Substring('0123456789ABCDEF',Substring(@bin_sid,@sid,1) / 16 + 1,
1) + Substring('0123456789ABCDEF',Substring(@bin_sid,@sid,1)%16 + 1,
1) + @string_sid,@sid = @sid - 1 END
SELECT @string_sid = ('0x' + @string_sid) END
/*导出login新建脚本*/
INSERT INTO ##scriptall(line)
SELECT CASE WHEN sp.TYPE = 'S' THEN '
/****** Object: Login ['+sp.name+'] Script Date: '+convert(varchar,GETDATE(),25)+' ******/
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
ELSE
'/****** Object: Login ['+sp.name+'] Script Date: '+convert(varchar,GETDATE(),25)+' ******/
CREATE LOGIN [' + sp.name + '] FROM WINDOWS WITH DEFAULT_DATABASE=[' + sp.default_database_name + ']'
END
FROM sys.sql_logins sl
RIGHT JOIN sys.server_principals sp
ON sl.sid = sp.sid
JOIN sys.syslogins s
ON s.sid = sp.sid
WHERE sp.TYPE IN ('S','G','U')
AND sp.name = @loginame
END /*结果集输出*/
IF @filepath IS NULL
BEGIN
SELECT line
FROM ##scriptall
ORDER BY id ASC
DROP TABLE ##scriptall
END
ELSE
BEGIN
declare @cmd varchar(1000)
SELECT @cmd = 'master..xp_cmdshell ''bcp "select line from ##ScriptAll order by id" queryout ' + @filepath + ' -T -c -S' + @@SERVERNAME + ''''
EXEC( @cmd)
DROP TABLE ##scriptall
END
SQL Server 服务器器信息备份(一)--login新建脚本备份的更多相关文章
- 由于服务器意外的断电,导致SQL SERVER服务器上数据库出现“置疑”而无法使用,
来自百度 1.停止数据库服务器,将数据库MDF文件和LDF文件复制备份一份2.启动数据库服务器,删除置疑的数据库3.仅用备份的数据库MDF文件附加数据库,sp_attach_db或者sp_attach ...
- 人人都是 DBA(III)SQL Server 调度器
在 SQL Server 中,当数据库启动后,SQL Server 会为每个物理 CPU(包括 Physical CPU 和 Hyperthreaded)创建一个对应的任务调度器(Scheduler) ...
- SQL Server服务器名称与默认实例名不一致的修复方法
SQL Server服务器名称与默认实例名不一致的修复方法 分类: 个人累积 SQl SERVER 数据库复制2011-08-10 09:49 10157人阅读 评论(0) 收藏 举报 sql ser ...
- 解决SQL Server管理器无法连接远程数据库Error: 1326错误
解决SQL Server管理器无法连接远程数据库Error: 1326错误 我们在在使用SQL Server时都会遇到使用SQL Server Management Studio无法连接远程数据库实例 ...
- SQL Server 服务器磁盘测试之SQLIO篇
原文:SQL Server 服务器磁盘测试之SQLIO篇 数据库调优工作中,有一部分是需要排查IO问题的,例如IO的速度或者RAID级别无法响应高并发下的快速请求.最常见的就是查看磁盘每次读写的响应速 ...
- Windows10中“SQL Server 配置管理器”哪去了?
SQL Server 配置管理器是一种工具,用于管理与 SQL Server 相关联的服务.配置 SQL Server 使用的网络协议以及从 SQL Server 客户端计算机管理网络连接配置.SQL ...
- 监控目前所有连接SQL SERVER的用户信息
原文:监控目前所有连接SQL SERVER的用户信息 if object_id('p_getlinkinfo','P')is not null drop proc p_getlinkinfo go c ...
- 在非SQL客户端使用命令行方式定期连接SQL Server 服务器并模拟用户查询操作,同时输出信息内容
一个很长的标题,实现的功能就是尽量使用非人力的方式模拟人去做一件事情,为了便于记录,将他们输出成文件方便查阅. 图形界面方式,使用微软自己的ConnMaker.exe,或者Microsoft 数据连接 ...
- SQL Server优化器特性-隐式谓词
我们都知道,一条SQL语句提交给优化器会产生相应的执行计划然后执行输出结果,但他的执行计划是如何产生的呢?这可能是关系型数据库最复杂的部分了.这里我为大家介绍一个有关SQL Server优化器的特性- ...
随机推荐
- 洛谷P1629 邮递员送信
题目描述 有一个邮递员要送东西,邮局在节点1.他总共要送N-1样东西,其目的地分别是2~N.由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有M条道路,通过每条道路需要一定的时间.这个邮递员每 ...
- ecshop /pick_out.php SQL Injection Vul By Local Variable Overriding
catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 在进行输入变量本地模拟注册的时候,没有进行有效的GPC模拟过滤处理,导出 ...
- WCF入门
一.概述 Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,可以翻译为Windows通讯接口,它是.NET框架的一部分.由 .NE ...
- 同样有缓冲区,为什么bufferedReader输入流不需要清空缓冲区?而bufferedWriter需要清空缓冲区呢?
当BufferedReader在读取文本文件时,会先尽量从文件中读入字符数据并置入缓冲区,而之后若使用read()方法,会先从缓冲区中进行读取, 如果缓冲区数据不足,才会再从文件中读取.清不清空Buf ...
- JS-用js的for循环实现九九乘法表以及其他算数题等
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>f ...
- SSH项目与SSM项目的进入首页的方法
SSH项目中: jsp页面一般都是存放在WEB-INF下面的目录下,这样我们就不能直接访问到这些jsp页面了,保证了页面的安全性. 在struts的管理中,是利用action来实现页面的跳转,进入in ...
- 如何排查APP服务端和客户端是否支持ATS
服务端排查 取得客户端直接连接的服务端域名及端口,例如mob.com.cn,端口443,即HTTPS默认端口.针对公网可访问的生产环境地址,建议使用的在线监测工具.https://wosign.ssl ...
- 10月23日上午PHP数组
正则表达式 1.替换 $s = "hello5world"; $s = preg_replace("/\d/","#",$s); echo ...
- Android学习笔记——CheckBox
该工程的功能实现在一个activity中显示一个单选框和一个多选框 以下代码是MainActivity.java文件中的代码 package com.example.checkbox; import ...
- 《CSS3实战》读书笔记 第三章:选择器:样式实现的标记
第三章:选择器:样式实现的标记 选择器的魔力在于,让你完全实现对网页样式的掌控.不同的选择器可以用在不同的情况下使用.总之把握的原则是:规范的编码,根据合理地使用选择器,比去背选择器的定义有价值的多. ...