博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
通过SqlClr制作Sql自动化批量执行脚本
阅读量:5076 次
发布时间:2019-06-12

本文共 5563 字,大约阅读时间需要 18 分钟。

通过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 FileName15         {16             get { return _FileName; }17             set { _FileName = value; }18         }19         private string _FilePath;20 21         public string FilePath22         {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
list = new List
();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         else23         {24             return new SqlString("失败");25         }26     }27 };

5.2写执行脚本:

--开启sqlclrsp_configure 'show advanced options', 1; GO RECONFIGURE; GO sp_configure 'clr enabled', 1; GO RECONFIGURE; GO--使用.net frameworkALTER database Test SET TRUSTWORTHY ONALTER assembly DataImprotwith permission_set = external_accessgo----开启【xp_cmdshell】权限exec sp_configure 'xp_cmdshell', @configvalue = 1reconfigure with overridego--开启【opendatasource】权限exec sp_configure @configname = 'Ad Hoc Distributed Queries', @configvalue = 1reconfigure 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'--日志文件路径.txtSET @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 datetimedeclare @EndTime datetimedeclare @sqlStr nvarchar(200)declare cur_FilePath cursor for select [FileName], [FilePath] from @FilePathTableopen cur_FilePath  fetch next from cur_FilePath into @FileName, @FilePathwhile (@@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, @FilePathendclose cur_FilePathdeallocate cur_FilePathselect * FROM #CurFilePathTableDROP TABLE #CurFilePathTable

5.3总结:

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

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

 

 

转载于:https://www.cnblogs.com/guozefeng/p/3705064.html

你可能感兴趣的文章
提取电话号码
查看>>
无需***,轻松提速 Github
查看>>
SVN 常识
查看>>
对类前置声明和包含头文件的一点理解
查看>>
小学生四则运算APP核心代码公布
查看>>
Luogu P4513 小白逛公园
查看>>
[BZOJ2118/Luogu2371][国家集训队]墨墨的等式
查看>>
学习笔记
查看>>
建表、添加数据及数据查询
查看>>
PHPCMS的自增长标签
查看>>
函数逆向分析
查看>>
scala面向对象.高阶函数,柯里化,Actor编程简介
查看>>
MySQL中对于NULL值的理解和使用教程
查看>>
opencv学习之路(26)、轮廓查找与绘制(五)——最小外接矩形
查看>>
poj 2503(字符串)
查看>>
C# 自定义OpenFileDialog屏蔽一些功能,缩略图显示文件夹,文件等等
查看>>
[baoj3224]普通平衡树
查看>>
POJ3087:Shuffle'm Up(模拟)
查看>>
Redis快速入门
查看>>
《Entity Framework 6 Recipes》中文翻译系列 目录篇 -持续更新
查看>>