通过SqlClr制作Sql自动化批量执行脚本

通过SqlClr制作Sql自动化批量执行脚本

在与同事一起做项目时,看到同事用sqlclr做批量执行脚本,感觉挺新奇的就上网搜集资料自己模仿跟做了个案例,

感觉挺不错的,现在想和大家分享一下,可能存在些错误的地方,大家就做个小参考吧....

1.我们在做数据迁移或是数据库结构修改时,通常会写一些脚本文件之后逐个运行。但是如果有数十或数百个脚本文件,

那么就可以通过SqlClr制作Sql自动化执

2.比如现在ImportDataScript文件夹内有些脚本文件:

3.我们想让这9个脚本文件自动的依次执行,并且输出最终的执行情况并且生成一个日志写到ImportDataScript文件夹内的

LogFile文件夹内的Logg.txt中。

4.我们预期结果:

执行结果:(执行每个文件的开始时间、结束时间、执行总时间)

输出日志:(名称、执行时间)

5.思路:首先我们通过sqlclr创建一个表值函数来获取脚本文件的本地路径的集合,然后遍历这个集合并通过sql exec
xp_cmdshell命令

来执行指定路径下的脚本文件,并通过sqlclr创建一个记录日志的的标量函数来逐条记录执行日志。

5.1创建sqlclr项目

5.1.1创建实体类:


 1 public class FilePathModel
2 {
3 public FilePathModel()
4 {
5
6 }
7 public FilePathModel(string fileName, string filePath)
8 {
9 this.FileName = fileName;
10 this.FilePath = FilePath;
11 }
12 private string _FileName;
13
14 public string FileName
15 {
16 get { return _FileName; }
17 set { _FileName = value; }
18 }
19 private string _FilePath;
20
21 public string FilePath
22 {
23 get { return _FilePath; }
24 set { _FilePath = value; }
25 }
26 }

5.1.2创建表值函数:


 1 public partial class UserDefinedFunctions
2 {
3 [Microsoft.SqlServer.Server.SqlFunction
4 (DataAccess = DataAccessKind.Read,
5 TableDefinition = "FileName nvarchar(100),FilePath nvarchar(100)",
6 FillRowMethodName = "FillTable", IsDeterministic = true)]
7 public static IEnumerable GetScriptFilePath(SqlString fileRootPath)
8 {
9
10 IList<FilePathModel> list = new List<FilePathModel>();
11 if (Directory.Exists(fileRootPath.Value))
12 {
13 DirectoryInfo di = new DirectoryInfo(fileRootPath.Value);
14 foreach (FileInfo fi in di.GetFiles())
15 {
16 list.Add(new FilePathModel { FileName=fi.Name,FilePath=fi.FullName});
17 }
18 }
19 return list;
20 }
21 public static void FillTable(object obj, out SqlString fileName, out SqlString filePath)
22 {
23 fileName = "";
24 filePath = "";
25 FilePathModel fpModel = obj as FilePathModel;
26 if (fpModel != null)
27 {
28 fileName = fpModel.FileName;
29 filePath = fpModel.FilePath;
30 }
31 }
32 };

5.1.3创建写入日志的标量函数:


 1 public partial class UserDefinedFunctions
2 {
3 [Microsoft.SqlServer.Server.SqlFunction]
4 public static SqlString ImportLog(SqlString pathStr, SqlString strName, SqlString Time)
5 {
6 // 在此处放置代码
7
8 if (Directory.Exists(pathStr.Value))
9 {
10 string filePathNew = Path.Combine(pathStr.Value, "Logg.txt");
11 FileInfo fi = new FileInfo(filePathNew);
12 if (!File.Exists(filePathNew))
13 {
14 fi.Create();
15 }
16 using (StreamWriter sw = fi.AppendText())
17 {
18 sw.WriteLine(strName.Value + "||" + Time.Value);
19 }
20 return new SqlString("完成");
21 }
22 else
23 {
24 return new SqlString("失败");
25 }
26 }
27 };

5.2写执行脚本:


--开启sqlclr
sp_configure ‘show advanced options‘, 1;
GO
RECONFIGURE;
GO
sp_configure ‘clr enabled‘, 1;
GO
RECONFIGURE;
GO
--使用.net framework
ALTER database Test SET TRUSTWORTHY ON
ALTER assembly DataImprot
with permission_set = external_access
go
--
--开启【xp_cmdshell】权限
exec sp_configure ‘xp_cmdshell‘, @configvalue = 1
reconfigure with override
go

--开启【opendatasource】权限
exec sp_configure @configname = ‘Ad Hoc Distributed Queries‘, @configvalue = 1
reconfigure with override

--测试
DECLARE @fileRootPath nvarchar(100)
DECLARE @logFilePath nvarchar(100)
DECLARE @serverName nvarchar(100)
DECLARE @dataBaseName nvarchar(100)
DECLARE @loginName nvarchar(100)
DECLARE @passWord nvarchar(100)
--服务器名
SET @ServerName=‘PACTERA_GZF-PC‘
--数据库名
SET @dataBaseName=‘Test‘
--用户名
SET @loginName=‘sa‘
--密码
SET @passWord=‘sa‘
--脚本根路径
SET @fileRootPath=‘D:\ImportDataScript‘
--日志文件路径.txt
SET @logFilePath=‘D:\ImportDataScript\LogFile‘
DECLARE @FilePathTable table
(
[FileName] nvarchar(100),
FilePath nvarchar(100)
)
create table #CurFilePathTable
(
Id int identity(1,1) primary key,
[FileName] nvarchar(100),
FilePath nvarchar(100),
BeginTime datetime,
EndTime datetime,
ExcuteDate float
)
insert into @FilePathTable select [FileName], [FilePath] from dbo.GetScriptFilePath(@fileRootPath)
declare @FileName nvarchar(100)
declare @FilePath nvarchar(100)
declare @BeginTime datetime
declare @EndTime datetime
declare @sqlStr nvarchar(200)
declare cur_FilePath cursor for select [FileName], [FilePath] from @FilePathTable
open cur_FilePath
fetch next from cur_FilePath into @FileName, @FilePath
while (@@fetch_status = 0)
begin
set @BeginTime = getdate()
set @sqlStr = ‘exec xp_cmdshell ‘‘osql -S ‘+@ServerName+‘ -U ‘+@loginName+‘ -P ‘+@passWord+‘ -i ‘ + @FilePath + ‘‘‘‘
exec master..sp_executesql @sqlStr
set @EndTime = getdate()
print @FileName
insert into #CurFilePathTable ([FileName], FilePath, BeginTime,EndTime,ExcuteDate) values (@FileName, @FilePath, @BeginTime,@EndTime,datediff(second, @BeginTime, @EndTime))
select dbo.ImportLog(@logFilePath,@FileName,convert(varchar(10),datediff(second, @BeginTime, @EndTime)))
fetch next from cur_FilePath into @FileName, @FilePath
end
close cur_FilePath
deallocate cur_FilePath

select * FROM #CurFilePathTable
DROP TABLE #CurFilePathTable

5.3总结:

感觉SqlClr就像是插件模型,通过嵌入.dll来实现更多的功能。

利用SqlClr我们可以做许事情比如我们也可以在sqlserver端实现数据的加密解密等。

通过SqlClr制作Sql自动化批量执行脚本

时间: 2024-10-21 14:08:57

通过SqlClr制作Sql自动化批量执行脚本的相关文章

Oracle批量执行脚本文件

以下是Oracle批量执行脚本文件的步骤和方法 1.创建脚本文件(xx.sql): 例如文件CreateTable Create table tb1( id varchar2(30), Name varchar2(50) ); Commit; / 可以创建多个,但是要注意语句之间要以分号结尾,同时注意语句内尽量不要有空行,因为空行的时候,在批量执行时可能会报错. 例如创建表时 create table t( id varchar2(20), Name varchar2(30) ); 上面这个文件

sqlplus批量执行脚本日志输出

spool d:\eagle2_2014_5_9_init.log; set feedback off; set define off; prompt -----初始化数据 start--- @D :\projects\Eagle_V2\04Code\v2.0\eagle2\resources\database\full\coc\coc-initialize.sql @D :\projects\Eagle_V2\04Code\v2.0\eagle2\resources\database\full

2.3-命令批量执行脚本

命令批量执行脚本,同样需要两个脚本来实现:1 exe.expect 2 exe.sh 3 ip.list    IP列表 cat exe.expect #!/usr/bin/expect set host [lindex $argv 0]            #第一个参数,IP列表 set passwd "hd792310" set cm [lindex $argv 1]              #第二个参数,cm要执行的命令 spawn ssh [email protected]

python 批量执行脚本(服务端和客户端建立TCP连接)

有很多开源的批量部署的工具可以使用,比如puppet, ansible , saltstack , chef . 但这些工具都有自己的一套语法规则,你得按照他的语法来编写程序,然后批量执行. 那有没有方法可以直接写bash 或者Python脚本,然后批量执行呢? 方法当然是有的,需要自己写程序来传输脚本,拷贝文件,再复杂点,可以自定义脚本式同步还是异步执行,自定义要执行的主机组,等等,需要根据自己的业务需要来想. 这里只是抛砖引玉,我采用建立socket(TCP)连接来批量执行脚本. 服务端脚本

分发系统:命令批量执行脚本

该脚本实现对不同主机批量执行命令 [[email protected] ~]# cat exe.expect#!/usr/bin/expect set host [lindex $argv 0] set passwd "123456" set cm [lindex $argv 1] spawn ssh [email protected]$host expect { "yes/no" { send "yes\r"} "password:&

python自动化--批量执行测试之生成报告

一.生成报告 1.先执行一个用例,并生成该用例的报告 # -*- coding: utf-8 -*- from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import Select from selenium.common.except

Jmeter 批量执行脚本之-----------Ant

一.环境介绍&准备: 1)jmeter3.2版本,需配备jdk1.8(或其他jmeter版本): 2)ant下载,并配置环境变量: a.下载地址:http://ant.apache.org/bindownload.cgi b. 配置环境变量: c.检查是否生效:命令行输入ant -v,出现以下表示成功 3)拷贝jar包:将 jmeter的extras目录中ant-jmeter-1.1.1.jar包拷贝至ant安装目录下的lib目录中 4)修改Jmeter的bin目录下jmeter.propert

sql server 执行上100mb sql sql sql server 无法执行脚本 没有足够的内存继续执行

cmd osql -S 服务器名称 -E sql文件路径 ------------------------------------------------------ 最近遇到一个问题,在sqlserver的查询分析器里面执行一个超过100MB的数据库脚本,发现老是报“引发类型为“System.OutOfMemoryException”的异常”,上网查了一下,主要是因为.sql的脚本文件过大(一般都超过100M)造成内存无法处理这么多的数据. 解决办法有各种各样,例如: 1.用记事本打开脚本文件

利用Python的unittest单元测试框架的discover方法批量执行脚本用例

1.在用Python自动化时,执行单个脚本用例那都是so easying当脚本用例不断地增多时,那就蒙蔽了,一个个来跑到什么时候才跑完,所以discover方法作用就出来,废话不多,小编直接上代码了,如有疑问,可以咨询小编 #!/usr/bin/python# -*- coding: utf-8 -*-from selenium import webdriverimport time,osfrom selenium.webdriver.common.action_chains import Ac