SQL Server 合并SQL脚本文件的方法的简单示例

感兴趣的小伙伴,下面一起跟随编程之家 jb51.cc的小编两巴掌来看看吧!

概述
--------------------------------------------------------------------------------
在平时的工作中,我会经常的碰到这样需要合并SQL脚本的问题。如,有很多的SQL脚本文件,需要按照一定的先后顺序,再生成一个合并SQL脚本文件,然后再发布到用户SQL Server服务器上。
合并SQL脚本文件,最直接的方法就是新建1个空白的SQL脚本文件,再把需要合并的SQL脚本文件内容复制到新建的SQL文件中。当初,我合并脚本的操作方法与刚说的有类似。我在Microsoft SQL Server Management Studio(MSSMS)新建一个查询,再把要合并的SQL脚本文件,一个一个的打开,并复制内容到新建查询中,然后生成合并脚本文件。
上面的方法,对于几个SQL脚本文件合并来说,似乎没什么问题。但是,当我们要合并的脚本很多,一文件一个文件的内容复制,是比较繁琐的事情,要是能有1个简单合并脚本工具就最好不过了。下面介绍我写的两个合并SQL脚本文件的存储过程.
第1个存储过程,只要调用sp_OACreate实现合并SQL脚本文件。

代码如下:

 
use master 
Go 
if object_id('sp_ScriptMerge') Is Not Null 
Drop proc sp_ScriptMerge 
Go 
Create Proc sp_ScriptMerge 
( 
@Path nvarchar(1024),@FilesList nvarchar(max)= null,@NewFileName nvarchar(1024)=null 
) 
As 
/*合并SQL脚本文件(SQL)V1.0 Andy 2011-9-1*/ 
Declare 
@ScriptNr nchar(21),@subdirectoryStr nvarchar(512),@Dir nvarchar(1024),@ScriptCount int 
Declare @subdirectoryTB Table (subdirectory nvarchar(512),depth smallint,[file] smallint) 
Declare @tmp table(row smallint identity primary key,fileName nvarchar(512)) 
Set Nocount on 
if right(@Path,1)<>'\' Set @Path=@Path+'\' 
If Isnull(@NewFileName,'')='' Set @NewFileName=N'合并脚本-'+Convert(nvarchar(8),getdate(),112) 
if lower(right(@NewFileName,4))<>'.sql' Set @NewFileName=@NewFileName+'.sql' 
Set @NewFileName=@Path+@NewFileName 
Set @ScriptNr='Nr: '+Replace(replace(Replace(replace(convert(nvarchar(23),121),'-',''),':',' ','.','') 
Set @ScriptCount=0 
/*读取脚本文件内容*/ 
if @FilesList >'' 
Begin 
Set @FilesList='Select N'''+replace(@FilesList,',''' Union All Select N''')+'''' 
Insert into @tmp([fileName]) Exec(@FilesList) 
End 
if object_id('Tempdb..#') Is Not Null Drop Table # 
Create table #(row int identity(1,1) Primary key,text nvarchar(max)) 
Insert into @subdirectoryTB Exec xp_dirtree @Path,1,1 
Declare cur_file cursor for 
Select a.subdirectory 
From @subdirectoryTB As a 
left Join @tmp As b ON b.fileName=a.subdirectory 
Where a.[file]=1 And a.subdirectory like '%.sql' 
And (b.fileName=a.subdirectory Or Not Exists(Select 1 From @tmp)) 
Order By isnull(b.row,0),a.subdirectory 
Open cur_file 
fetch next From cur_file into @subdirectoryStr 
While @@FETCH_STATUS = 0 
Begin 
Set @ScriptCount=@ScriptCount+1 
Insert into #(text) Select +Char(13)+Char(10)+ N'Go'+Char(13)+Char(10)+ N'/* '+@ScriptNr+' ('+rtrim(@ScriptCount)+'): '+@subdirectoryStr+' */'+Char(13)+Char(10)+ N'Go'+Char(13)+Char(10) 
Set @Dir='Type '+@Path+''+@subdirectoryStr+'' 
Insert into #(text) 
Exec sys.xp_cmdshell @Dir 
fetch next From cur_file into @subdirectoryStr 
End 
Close cur_file 
Deallocate cur_file 
if @ScriptCount >0 Insert into #(text) Select +Char(13)+Char(10)+ N'Go'+Char(13)+Char(10)+ N'/* '+@ScriptNr+' 合并完成(合计 '+rtrim(@ScriptCount)+' 各脚本文件). */'+Char(13)+Char(10)+ N'Go'+Char(13)+Char(10) 
/*写入合并脚本文件*/ 
if @ScriptCount>0 
Begin 
Declare @object int,@FileID int,@hr int,@src varchar(255),@desc varchar(255),@row int,@text nvarchar(max) 
Exec @hr=sp_OACreate 'Scripting.FileSystemObject',@object output 
If @hr <> 0 Goto File_ErrorHandler 
Exec @hr = sp_OAMethod @object,'CreateTextFile',@FileID OUTPUT,@NewFileName 
If @hr <> 0 Goto File_ErrorHandler 
Set @row=1 
While Exists(Select 1 From # Where row=@row) 
Begin 
Set @text=(Select text From # Where row=@row) 
Exec @hr = sp_OAMethod @FileID,'WriteLine',NULL,@text 
Set @row=@row +1 
End 
Goto File_Done 
File_ErrorHandler: 
Print N'*********** 读写文件的时候发生错误 ***********' 
Exec @hr=sp_OAGetErrorInfo @object,@src OUT,@desc OUT 
Select convert(varbinary(4),@hr) As hr,@src As Source,@desc As Description 
File_Done: 
Exec @hr = sp_OADestroy @FileID 
Exec @hr = sp_OADestroy @object 
Print N'*********** 合并脚本完成 ***********' 
Print N'合并后脚本文件: '+@NewFileName 
End 
Go 

调用上面存储过程前,需要确认启用 OLE Automation Procedures和xp_cmdshell 选项:

代码如下:

 
调用上面存储过程前,需要确认启用 OLE Automation Procedures和xp_cmdshell 选项:

代码如下:

 
Exec sys.sp_configure @configname = 'show advanced options',@configvalue = 1 
reconfigure 
go 
Exec sys.sp_configure @configname = 'xp_cmdshell',@configvalue = 1 
reconfigure 
Go 
Exec sys.sp_configure @configname = 'Ole Automation Procedures',@configvalue = 1 
reconfigure 
Go 

测试:

代码如下:

 
use master 
GO 
Exec master.dbo.sp_ScriptMerge 
@Path = 'C:\Users\Administrator\Desktop\temp',-- nvarchar(1024) 
@FilesList = '',-- nvarchar(max) 
@NewFileName = '合并脚本20110905.sql' -- nvarchar(1024) 

*********** 合并脚本完成 ***********合并后脚本文件: C:\Users\Administrator\Desktop\temp\合并脚本20110905.sql第2个是CLR存储过程,使用C#代码实现合并SQL脚本文件。
--------------------------------------------------------------------------------
C#代码:

代码如下:

 
using System; 
using System.Data; 
using System.Data.SqlClient; 
using Microsoft.SqlServer.Server; 
using System.Data.SqlTypes; 
using System.IO; 
using System.Text; 
public class clScriptMerge 
{ 
[Microsoft.SqlServer.Server.SqlProcedure] 
public static void SQLScriptMerge(string Path,string FilesList,string NewFileName) 
{ 
try 
{ 
string[] strFiles ; 
FileInfo[] myFileInfo = (new DirectoryInfo(Path)).GetFiles(*.sql); 
string strScriptNr = @Nr + DateTime.Now.ToString(yyyyMMddHHmmssFFF); 
int intCount=0; 
if (NewFileName == null || NewFileName==) 
{ 
NewFileName = 合并脚本 + DateTime.Now.ToString(yyyyMMdd) + .sql; 
} 
SqlContext.Pipe.Send(NewFileName.ToString()); //打印已合并的SQL文件名 
// 1.获得SQL脚本列表 
if (FilesList != ) 
{ 
strFiles = FilesList.Split(','); //筛分SQL脚本文件名列表,以,分隔 
} 
else 
{ 
strFiles = new string[myFileInfo.Length]; 
for (int i = 0; i < myFileInfo.Length; i++) 
{ 
strFiles[i] = myFileInfo[i].Name; 
} 
} 
// 2.合并脚本 
SqlContext.Pipe.Send(【SQL脚本文件列表】:\n--------------------------------------------); 
StreamWriter SW = new StreamWriter(Path + @\ + NewFileName,true,Encoding.Unicode); //使用Unicode编码 
SW.WriteLine(@Go\n/*============  + strScriptNr + ====Start===================================*/\nGo\n); //记录生成的合并脚本编号&合并动作的开始位置 
foreach (string strFile in strFiles) 
{ 
if (strFile !=NewFileName) 
{ 
intCount += 1; 
SW.WriteLine(@/*  + strScriptNr +@ (+intCount+@):  + strFile + */\nGo\n); //记录合并哪一个脚本文件 
using (StreamReader SR = new StreamReader(Path + @\ + strFile,Encoding.Default)) 
{ 
string line; 
while ((line = SR.ReadLine()) != null) 
{ 
SW.WriteLine(line); 
} 
SR.Close(); 
} 
SqlContext.Pipe.Send(strFile.ToString()); //打印已合并的SQL文件名 
} 
} 
SW.WriteLine(@/*============  + strScriptNr + ====End (一共  + intCount +  个文件)===================================*/\nGo\n); //记录生成的合并脚本文件个数&合并动作的结束位置 
SW.Close(); 
SqlContext.Pipe.Send(\n\n【合成后文件】:\n--------------------------------------------\n + NewFileName); 
} 
catch (System.Exception e) 
{ 
SqlContext.Pipe.Send(\n在方法SQLScriptMerge内发生错误: \n\n + e.ToString()); 
} 
} 
} 

存储过程代码:

代码如下:

 
Use master 
GO 
--启动CLR 
Exec sp_configure 'clr enable',1 
Go 
Reconfigure 
GO 
--先设置数据库选项 
Alter Database Master Set TRUSTWORTHY On 
Go 
--存储过程 
If object_id('sp_ScriptMerge2') Is Not Null 
Drop Proc sp_ScriptMerge2 
Go 
If Exists(Select 1 From sys.assemblies Where Name=N'ScriptMerge') 
Drop Assembly ScriptMerge 
Go 
Create Assembly ScriptMerge 
From 'E:\Test\Objects\ISTest\ScriptMerge\ScriptMerge\bin\Debug\ScriptMerge.dll' 
create proc sp_ScriptMerge2 
( 
@Path nvarchar(1024),@FilesList nvarchar(max),@NewFileName nvarchar(1024) 
) 
As External Name ScriptMerge.clScriptMerge.SQLScriptMerge 
Go 

以上的CLR存储过程代码是在SQL Server 2005 & Microsoft Visual Studio 2005下运行通过。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


本篇内容主要讲解“sqlalchemy的常用数据类型怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“sqlalche...
今天小编给大家分享一下sqlServer实现分页查询的方式有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家
这篇文章主要介绍“sqlmap之osshell怎么使用”,在日常操作中,相信很多人在sqlmap之osshell怎么使用问题上存在疑惑,小编查阅了各式资料,整理出
本篇内容介绍了“SQL注入的知识点有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧...
1. mssql权限sa权限:数据库操作,文件管理,命令执行,注册表读取等system。是mssql的最高权限db权限:文件管理,数据库操作等 users-administratorspublic权限:数据库操作 guest-users2、sql server注入执行命令查
sql执行计划如何查看?在SPL庞大的数据中我们不知道如何查看实际数据库中发生了什么事情,有必要定期进行查询优化和索引否则会影响我们后期的SQL的查询速度。那么针对这样的问题我们必须要知道SQL执行的计划,在本文中winwin7小编给大家分享下SQL执
SQL Server 是Microsoft 公司推出的关系型数据库管理系统。具有使用方便可伸缩性好与相关软件集成程度高等优点应用非常广泛。不过在使用中,我们会遇到非常多的错误,面对这么庞大的数据库环境,当然会有精确的错误代码的对照季,下面小编分享的
SQL Server本地账户无法登陆出现错误提示:error:40-Could not open a connenction to SQL Server的问题很常见,对于初学者来说可能不知道如何解决,一起来看看下面的解决方案。解决步骤如下:1、这种情况需要开启 SQL Server service
微软推出的SQL2008是一款非常好用的数据库软件,它稳定、功能强大,为众多企业提供了最佳的数据库解决方案,那么我们如何在Windows中安装它呢,一些朋友对SQL Server 2008的安装过程还不是很熟悉,下面就一起来看看SQL Server 2008详细安装图解...
本页概要如果您使用的是 SQL Server 2005备份和还原Sp_detach_db 和 Sp_attach_db 存储过程关于排序规则的说明导入和导出数据(在 SQL Server 数据库之间复
DBCC CHECKIDENT 检查指定表的当前标识值,如有必要,还对标识值进行更正。 语法 DBCC CHECKIDENT ( &#39;table_name&#39; [ , { NORESEED
这里对 SQL Server 字符串函数进行分门别类地列出,便于查阅和记忆,相信大家都在其它方面有高深的编程基础,从字面上来说大家都知道这些函数的意义,就不对这些函数作过多的解释了,主要谈些经验,具体
查询及删除重复记录的方法 1、查找表(people)中多余的重复记录,重复记录是根据单个字段(peopleId)来判断select*frompeoplewherepeopleIdin(selectpe
微软发SQL Server 2008第二个CTP预览版from: http://news.csdn.net/n/20070807/107158.html8月7日消息,微软公司本周发布了SQL Serv
症状当您将数据库备份恢复到另一台服务器时,可能会遇到孤立用户的问题。SQL Server 联机丛书中的孤立用户疑难解答主题中没有讲述解决此问题的具体步骤。本文介绍了如何解决孤立用户问题。更多信息虽然术
当登录SQL Server 2005时可能碰到错误: &#39;No Process is on the Other End of the Pipe&#39;。解决方法:(1)Open up SQL
概要本文描述如何映射标准登录和集成登录来解决在运行 SQL Server 的服务器之间移动数据库时的权限问题。更多信息当您将数据库从一个运行 SQL Server 的服务器移到另一个运行 SQL Se
----------------------------------------问题:该用户与可信的SQL SERVER 连接无关联使用sa用户或自建用户使用“SQL SERVER 身份认证”连接数据
更新日期: 2007 年 5 月 20 日 使用下表可以确定各种版本的 Microsoft SQL Server 2005 支持哪些功能。有关 SQL Server 2005 Enterprise E
当从Excel导入数据到Sql Sever中,可能会出现以下问题:&#xD;&#xA;对于指定的缓冲区大小而言,源列的数据太大