设为首页 收藏本站
查看: 1106|回复: 0

[经验分享] 通过SqlClr制作Sql自动化批量执行脚本

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2014-5-6 10:19:48 | 显示全部楼层 |阅读模式
通过SqlClr制作Sql自动化批量执行脚本
     在与同事一起做项目时,看到同事用sqlclr做批量执行脚本,感觉挺新奇的就上网搜集资料自己模仿跟做了个案例,
感觉挺不错的,现在想和大家分享一下,可能存在些错误的地方,大家就做个小参考吧....
1.我们在做数据迁移或是数据库结构修改时,通常会写一些脚本文件之后逐个运行。但是如果有数十或数百个脚本文件,
   那么就可以通过SqlClr制作Sql自动化执
2.比如现在ImportDataScript文件夹内有些脚本文件:
   http://images.cnitblog.com/i/401614/201405/031304567362159.png
3.我们想让这9个脚本文件自动的依次执行,并且输出最终的执行情况并且生成一个日志写到ImportDataScript文件夹内的
   LogFile文件夹内的Logg.txt中。
4.我们预期结果:
   执行结果:(执行每个文件的开始时间、结束时间、执行总时间)
   http://images.cnitblog.com/i/401614/201405/031304191271202.png
   输出日志:(名称、执行时间)
   http://images.cnitblog.com/i/401614/201405/031306239865680.png
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)",

    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端实现数据的加密解密等。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-18734-1-1.html 上篇帖子: SQL Server 多实例下的复制 下篇帖子: SqlServer跨域查询 制作
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表