如何通过批处理将SQL存储过程保存到.SQL文件

如何通过批处理将SQL存储过程保存到.SQL文件,sql,sql-server-2005,stored-procedures,export,Sql,Sql Server 2005,Stored Procedures,Export,我想将我的MS SQL Server 2005存储过程自动保存到.SQL文件(我更喜欢通过.bat调用的工具),这样我就不必手动单击每个存储过程并保存它 我已经从devio IT找到了SMOscript,但它收集了所有表和存储过程,这需要一些时间。是否有类似的工具可以定义要导出的存储过程?另外,我缺少了USE子句,SMOScript没有将其添加到导出的文件中,这与用于创建的manuall导出为脚本存储过程不同 致意 sean在SQL Server Management Studio中有一个替代方

我想将我的MS SQL Server 2005存储过程自动保存到.SQL文件(我更喜欢通过.bat调用的工具),这样我就不必手动单击每个存储过程并保存它

我已经从devio IT找到了SMOscript,但它收集了所有表和存储过程,这需要一些时间。是否有类似的工具可以定义要导出的存储过程?另外,我缺少了USE子句,SMOScript没有将其添加到导出的文件中,这与用于创建的manuall导出为脚本存储过程不同

致意
sean

在SQL Server Management Studio中有一个替代方案,为数据库编写脚本

展开“对象资源管理器”视图以查找数据库,右键单击并选择“任务:生成脚本”

从那里,您可以编写所有对象的脚本,包括存储在两者之间的任何内容。一个页面上有很多选项,但我更改的主要选项是: -“如果不存在,则包括”

通过将该选项设为“FALSE”,您将得到一个完整的CREATE语句列表


然后,您可以选择将对象编写到一个新的查询窗口或文件中。

不久前,我也想做同样的事情,最后制作了一个小vbscript


请看这里

使用脚本创建批处理文件(很抱歉格式化,但它确实应该是内联的,以便执行批处理):

将其命名为“run.bat”。现在,要执行批处理,请使用参数:
run.bat[用户名][密码][服务器名][数据库]
例如:
run.bat sa pwd111 localhost\SQLEXPRESS master
首先,所有存储过程名称将存储在文件sp_list.txt中,然后逐个存储在单独的脚本文件中。唯一的问题-每个脚本的最后一行有结果计数-我正在处理它:)

已编辑:已修复查询中的错误

删除“受影响的行”行
好的,现在我们需要再创建一个批次:

type %1 | findstr /V /i %2  > xxxtmpfile 
copy xxxtmpfile %1 /y /v
del xxxtmpfile
将其命名为“line_del.bat”。请参阅,第一个参数是要处理的文件,第二个参数是要搜索要删除的行的字符串。现在修改主批处理(同样,很抱歉格式化):

参见相关文章:




:)你可能会注意到,最后两个是从某某来的

我使用了sqlcmd和-E,而不是user,pass。到目前为止,这一切都很好,只要存储过程长度超过4000个字符,就会出现换行

sqlcmd -E -S SERVER -d DB -h-1 -Q "SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_TYPE = 'PROCEDURE'" -o "sp_list.txt"
call line_del sp_list.txt "rows affected"
call line_del sp_list.txt "row affected"
for /f %%a in (sp_list.txt) do sqlcmd -E -S SERVER -d DB -h-1 -Q "SELECT text from dbo.syscomments WHERE id = OBJECT_ID('%%a')" -o "%%a.sql"
for /f %%a in (sp_list.txt) do call line_del %%a.sql "rows affected"
for /f %%a in (sp_list.txt) do call line_del %%a.sql "row affected"
致意
肖恩

我添加了SETNOCOUNT ON,以消除对line_del.bat的需要。还将syscomments替换为sys.sql_模块(sql 2005)。我也可以使用OBJECT_DEFINITION函数,但它比sys.sql_模块慢

sqlcmd -E -S SERVER -d DB -h-1 -Q "SET NOCOUNT ON SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_TYPE = 'PROCEDURE'" -o "sp_list.txt" for /f %%a in (sp_list.txt) do sqlcmd -E -S SERVER -d DB -h-1 -Q "SET NOCOUNT ON SELECT definition from sys.sql_modules WHERE object_id = OBJECT_ID('%%a')" -o "%%a.sql"

添加SETNOCOUNT ON确实消除了对行_del.bat的需要,但是用sys.sql_模块替换syscomments会导致每个存储过程被截断为258个字符。因此,为了获得最佳效果,我使用的代码是:

sqlcmd -E -S SERVER-d DB -h-1 -Q "SET NOCOUNT ON SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_TYPE = 'PROCEDURE'" -o "sp_list.txt"
for /f %%a in (sp_list.txt) do sqlcmd -E -S SERVER-d DB -h-1 -Q "SET NOCOUNT ON SELECT text from dbo.syscomments WHERE id = OBJECT_ID('%%a')" -o "%%a.sql"
这是有效的,并且不需要使用line_del.bat。使用SSMS向导(任务/生成脚本/存储过程/全选)手动导出时,我没有得到的是:


在每个.sql的开头,以及后面的GO命令。不是特别重要,但需要注意。感谢Max Gontar、Seansilver和Lee的贡献!现在,我可以自动备份数据库中的存储过程,并应用版本控制。

感谢以上所有帮助,并将此留给其他像我这样的sqlcmd noobs查找。在SQLServer2005上工作。objectName是过程、视图等的名称

:reset

-- :setvar ObjectName "objectName"  -- works
:setvar ObjectName objectName  -- works too
declare @sql varchar(max);
set @sql = 'select text from dbo.syscomments where id = object_id(upper("' + '$(ObjectName)' + '"))';
-- exec sp_helptext $(ObjectName)  -- quick n easy but gets chopped to 256 width
/*   4000 byte limit
set @sql = 
   'select view_definition 
    from information_schema.views 
    where upper(table_name) = upper("' + '$(ObjectName)' + '")';
*/
:out $(ObjectName).sql

exec(@sql)
go

:out stdout

感谢您的提示,不幸的是,我认为这对我来说有一些缺点-我每次都必须手动完成所有步骤(无自动/批处理)-所有选定的存储过程都保存到一个.sql文件中-无注释保存谢谢!我试了一下,但在身份验证方面遇到了一些问题(osql无法连接)。我会在未来几天再试一次。。。最好的礼遇这次休息不适合大动作吗?当我运行时:从信息模式中选择例程名称max(len(例程定义))。例程按例程分组按例程名称按2描述排序;我有很多4000个字符的程序。非常确定您需要退出sys.comments以获得正确的数据。哎呀,这应该是上面注释中的syscomments。不是一个独立的答案,应该是您正在谈论的答案上的注释。
sqlcmd -E -S SERVER-d DB -h-1 -Q "SET NOCOUNT ON SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_TYPE = 'PROCEDURE'" -o "sp_list.txt"
for /f %%a in (sp_list.txt) do sqlcmd -E -S SERVER-d DB -h-1 -Q "SET NOCOUNT ON SELECT text from dbo.syscomments WHERE id = OBJECT_ID('%%a')" -o "%%a.sql"
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
:reset

-- :setvar ObjectName "objectName"  -- works
:setvar ObjectName objectName  -- works too
declare @sql varchar(max);
set @sql = 'select text from dbo.syscomments where id = object_id(upper("' + '$(ObjectName)' + '"))';
-- exec sp_helptext $(ObjectName)  -- quick n easy but gets chopped to 256 width
/*   4000 byte limit
set @sql = 
   'select view_definition 
    from information_schema.views 
    where upper(table_name) = upper("' + '$(ObjectName)' + '")';
*/
:out $(ObjectName).sql

exec(@sql)
go

:out stdout