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优化器的特性- ...
随机推荐
- 小米手机(HM1SW)高通开发android程序全过程
小米手机(HM1SW)开发android程序全过程 修改历史: 2016年5月9日 -------- 整理文档 a.增加了手机基本信息. b.增加360手机助手连接说明 2016年2月26日 - ...
- 数据结构算法C语言实现(十四)--- 4.1&4.2串的类型定义、表示及实现
一.简述 [暂无] 二.头文件 //4_2_part1.h /** author:zhaoyu */ //2016-6-10 //----串的定长顺序存储表示---- #include "h ...
- RabbitMQ安装配置
安装RabbitMQ windows下的安装是非常简单的,我们需要准备两个东西 erlang的环境 下载windows和与之对象的操作系统位数安装包 http://www.erlang.org/do ...
- ( 译、持续更新 ) JavaScript 上分小技巧(四)
后续如有内容,本篇将会照常更新并排满15个知识点,以下是其他几篇译文的地址: 第一篇地址:( 译.持续更新 ) JavaScript 上分小技巧(一) 第二篇地址:( 译.持续更新 ) JavaScr ...
- 导入.pch文件
Xcode5中创建一个工程的时候,系统会自动创建一个以以工程名为名字的pch(Precompile Prefix Header)文件,开发的过程中可以将广泛使用的头文件以及宏包含在该文件下,编译器就会 ...
- Alpha版本十天冲刺——Day 8
站立式会议 会议总结 队员 今天完成 遇到的问题 明天要做 感想 鲍亮 无 同时发送图片和其它字段信息(string)到服务器,找不到好方法实现 完成发帖接口 心累,写好了一个传送文件的接口,但是后端 ...
- 屠蛟之路_你的名字_FirstDay
君の名は. "号外,号外!屠龙天团众志成城,惊天技杀alpha龙!号外,号外--" 苦战十日,屠龙少年们依仗最后的惊天技终于将邪恶的alpha怪龙斩杀.但是对屠龙少年而言,这是一场 ...
- DockerProblem
if you try to run the daemon manually: sudo /usr/bin/docker daemon And the error is: "FATA[0000 ...
- css002 创建样式和样式表
创建样式和样式表 一个样式表包含多个样式 样式表的种类 1.内部样式表,存放在<head></head>之间.如: <head> <style> ( ...
- Python-层次聚类-Hierarchical clustering
层次聚类关键方法#coding:UTF-8#Hierarchical clustering 层次聚类from E_distance import Euclidean_distance from yez ...