原文:通过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创建实体类:

 public class FilePathModel
{
public FilePathModel()
{ }
public FilePathModel(string fileName, string filePath)
{
this.FileName = fileName;
this.FilePath = FilePath;
}
private string _FileName; public string FileName
{
get { return _FileName; }
set { _FileName = value; }
}
private string _FilePath; public string FilePath
{
get { return _FilePath; }
set { _FilePath = value; }
}
}

5.1.2创建表值函数:

 public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction
(DataAccess = DataAccessKind.Read,
TableDefinition = "FileName nvarchar(100),FilePath nvarchar(100)",
FillRowMethodName = "FillTable", IsDeterministic = true)]
public static IEnumerable GetScriptFilePath(SqlString fileRootPath)
{ IList<FilePathModel> list = new List<FilePathModel>();
if (Directory.Exists(fileRootPath.Value))
{
DirectoryInfo di = new DirectoryInfo(fileRootPath.Value);
foreach (FileInfo fi in di.GetFiles())
{
list.Add(new FilePathModel { FileName=fi.Name,FilePath=fi.FullName});
}
}
return list;
}
public static void FillTable(object obj, out SqlString fileName, out SqlString filePath)
{
fileName = "";
filePath = "";
FilePathModel fpModel = obj as FilePathModel;
if (fpModel != null)
{
fileName = fpModel.FileName;
filePath = fpModel.FilePath;
}
}
};

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

 public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlString ImportLog(SqlString pathStr, SqlString strName, SqlString Time)
{
// 在此处放置代码 if (Directory.Exists(pathStr.Value))
{
string filePathNew = Path.Combine(pathStr.Value, "Logg.txt");
FileInfo fi = new FileInfo(filePathNew);
if (!File.Exists(filePathNew))
{
fi.Create();
}
using (StreamWriter sw = fi.AppendText())
{
sw.WriteLine(strName.Value + "||" + Time.Value);
}
return new SqlString("完成");
}
else
{
return new SqlString("失败");
}
}
};

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自动化批量执行脚本的更多相关文章

  1. PL/SQL中批量执行SQL脚本(不可把所有的语句都复制到New SQL Windows)

    PL/SQL中批量执行SQL脚本,不可把所有的语句都复制到New SQL Window,因为这样会导致缓冲区过大而进程卡死! 最好的办法是将要执行的SQL脚本存放到指定文件中,如C:\insert.s ...

  2. Oracle批量执行脚本文件

    以下是Oracle批量执行脚本文件的步骤和方法 1.创建脚本文件(xx.sql): 例如文件CreateTable Create table tb1( id varchar2(30), Name va ...

  3. 利用bat批量执行脚本文件

    1.读取目录文件 利用bat 的for命令读取中的sql文件 for /r %%c in (0*.sql) do echo %%c %%c 相当于变量 in() 中的为循环的范围 此句的作用是显示当前 ...

  4. SaltStack 批量执行脚本

    这里演示如何使用 salt-master 对多台 salt-minion 批量执行脚本,步骤如下: [root@localhost ~]$ cat /srv/salt/top.sls # 先定义入口配 ...

  5. linux集群自动化搭建(生成密钥对+分发公钥+远程批量执行脚本)

    之前介绍过ansible的使用,通过ssh授权批量控制服务器集群 但是生成密钥和分发公钥的时候都是需要确认密码的,这一步也是可以自动化的,利用ssh + expect + scp就可以实现,其实只用这 ...

  6. 使用sqlplus批量执行脚本的总结

    当然,我们可以在plsql中执行,但是在实际生产环境中,可能更多的是使用简便的sqlplus.步骤如下: 1.登陆client sqlplus connect <username>/< ...

  7. bat+sqlcmd 批量执行脚本

    Hello,此BAT脚本能够帮助开发者将某目录下全部SQL脚本按文件名称依次在指定数据库中批量执行. 不用忍受powershell invoke-sqlcmd 的笨重.在指执行时多一种选择. bat文 ...

  8. py+selenium+IE 批量执行脚本10几分钟,IE会卡住【无解,提供绕过方法】

    问题:py+selenium+IE 批量执行单个脚本10几分钟,IE会卡住 一个脚本文件里有20几个用例,跑起来10多分钟,每次跑10分钟后(即第22条用例左右时)IE就会卡住,程序就会在那傻等,最后 ...

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

    一.环境介绍&准备: 1)jmeter3.2版本,需配备jdk1.8(或其他jmeter版本): 2)ant下载,并配置环境变量: a.下载地址:http://ant.apache.org/b ...

随机推荐

  1. 采用Flume实时采集和处理数据

    它已成功安装Flume在...的基础上.本文将总结使用Flume实时采集和处理数据,详细过程,如下面: 第一步,在$FLUME_HOME/conf文件夹下,编写Flume的配置文件,命名为flume_ ...

  2. C#分布式缓存Couchbase

    C#分布式缓存Couchbase使用 一.简介 目前C#业界使用得最多的 Cache 系统主要是 Memcached和 Redis. 这两个 Cache 系统可以说是比较成熟的解决方案,也是很多系统当 ...

  3. robot framework环境搭建(转)

    一. robot framework环境搭建: 官网:http://robotframework.org/ 序号 安装包名 安装方法 下载地址 备注 1 python exe文件,直接双击安装 htt ...

  4. BestCoder-Round#33

    写在前面 这是我第一次做BestCoder, 熟悉的外观BestCoder模式. BC上不仅能看到英文, 背部Chinese view是中文题目 交的次数是会影响得分的. 所以有了把握再交. 至少例子 ...

  5. crawler_httpurlconnection_自动编码识别

    核心思想: 1:从响应头中读取 [命中解流准确率最高] 2:如果响应头中没有,打开流从源码中读取,[取舍,如果有一般在前30行会有,前100行中寻找] 3:如果还没有,根据字节码code位置,字符识别 ...

  6. php_常用操作_读取文件_数据库操作

    作为php新手 ,把经常用到的phpcode,做个备份 1: 文件处理 //读取配置 启动是指定文件 $filepath=$argv[1]; if(null==$filepath){ echo&quo ...

  7. Tomcat剖析(四):Tomcat默认连接器(2)

    Tomcat剖析(四):Tomcat默认连接器(2) 1. Tomcat剖析(一):一个简单的Web服务器 2. Tomcat剖析(二):一个简单的Servlet服务器 3. Tomcat剖析(三): ...

  8. order by使用方法

    1.ORDER BY 中关于NULL的处理 缺省处理,Oracle在Order by 时觉得null是最大值,所以假设是ASC升序则排在最后,DESC降序则排在最前. 当然,你也能够使用nulls f ...

  9. hdu 1002 Java 大数 加法

    http://acm.hdu.edu.cn/showproblem.php?pid=1002 PE   由于最后一个CASE不须要输出空行 import java.math.BigInteger; i ...

  10. ZOJ3640之简单慨率DP

    Help Me Escape Time Limit: 2 Seconds      Memory Limit: 32768 KB Background     If thou doest well, ...