2009-02-20 77 views
8

我很想将我的MS SQL Server 2005存储过程自动保存为.sql文件(我倾向于使用可以通过.bat调用的工具),所以我不必点击每个单独的sproc手动并保存。如何通过批量将SQL存储过程保存到.sql文件

我已经从devio IT找到了SMOscript,但它收集了所有需要一些时间的表和sproc。是否有类似的工具可以定义要导出哪些sproc?此外,我缺少USO子句,SMOScript不会将其添加到导出的文件中,而与手动导出为CREATE的脚本存储器相反。

问候 肖恩

回答

5

创建脚本批处理文件(有关格式化抱歉,但它确实应该是内联执行批处理):

osql -U %1 -P %2 -S %3 -d %4 -h-1 -Q "SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_TYPE = 'PROCEDURE'" -n -o "sp_list.txt" 
for /f %%a in (sp_list.txt) do osql -U %1 -P %2 -S %3 -d %4 -h-1 -Q "SELECT ROUTINE_DEFINITION FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_NAME = '%%a'" -n -o "%%a.sql" 

将它命名为“的run.bat”。现在,为了执行批量使用PARAMS:
的run.bat [用户名] [密码] [服务器] [数据库]
上例如:
的run.bat SA pwd111本地主机\ SQLEXPRESS主
第一个所有存储过程名称将是存储在文件sp_list.txt中,然后在单独的脚本文件中逐个存储。唯一的问题 - 用结果计数每个脚本的最后一行 - 我干活的就可以了:)

编辑:错误查询固定

删除线
确定‘受影响的行’,现在我们需要再创建一个批次:

type %1 | findstr /V /i %2 > xxxtmpfile 
copy xxxtmpfile %1 /y /v 
del xxxtmpfile 

将其命名为“line_del.bat”。请参阅第一个参数是要处理的文件,第二个 - 字符串以搜索要删除的行。现在,修改主批次(再次,抱歉格式):

osql -U %1 -P %2 -S %3 -d %4 -h-1 -Q "SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_TYPE = 'PROCEDURE'" -n -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 osql -U %1 -P %2 -S %3 -d %4 -h-1 -Q "SELECT ROUTINE_DEFINITION FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_NAME = '%%a'" -n -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" 

见相关文章:
Simple programming commands in a batch environment
osql Utility
MSSQL: How do you script Stored Procedure creation with code?
Delete certain lines in a txt file via a batch file

:)你可能会注意到,最后两个是从所以!

+0

非常感谢!我尝试了一下,但在身份验证方面存在一些问题(osql can not connect)。在接下来的日子里我会再试一次...最好的问候 – seansilver 2009-02-23 16:27:05

+1

对于大型procs来说,这不会中断吗?当我运行:SELECT ROUTINE_NAME,max(len(ROUTINE_DEFINITION))FROM INFORMATION_SCHEMA.Routines group by ROUTINE_NAME order by 2 desc;我得到了很多4000个字符的特效。很确定你需要退出sys.coms以获得正确的数据。 – jcollum 2009-12-21 17:42:33

2

在SQL Server Management Studio中的替代,脚本数据库...

展开对象资源管理器视图来查找数据库,点击鼠标右键,选择“任务:生成脚本“

从那里你可以脚本所有的对象,只是存储prececedures,之间的任何东西。在一个页面上有很多选项,尽管我更改的主要选项是: - “包括IF NOT EXISTS”

通过使该选项为“FALSE”,您只需获取CREATE语句的整个列表。

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

+0

谢谢你的提示,不幸的是我这个对我来说 一些缺点 - 我要完成所有步骤,每次通过手(无自动/批) 去 - 所有选定的存储过程被保存到一个.SQL文件 - 未保存评论 – seansilver 2009-02-20 10:21:32

0

我用sqlcmd和-E代替用户,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" 

问候 肖恩

0

我加了SET NOCOUNT ON消除对line_del.bat的需要。还将syscomments替换为sys.sql_modules(SQL 2005)。我也可以使用OBJECT_DEFINITION函数,但比sys.sql_modules慢。

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" 
1

添加SET NOCOUNT ON确实消除对line_del.bat的需要,但随着sys.sql_modules更换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向导手动导出(任务/生成脚本/存储过程/全选)是:

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

在每个.SQL的开始,并且后GO命令还。不是非常重要,但需要注意的地方。感谢Max Gontar,Seansilver和Lee的贡献!我现在可以自动备份数据库中的存储过程,并应用版本控制。

0

感谢上述所有人的帮助,并将其留给了像我这样的其他sqlcmd noobs。适用于sql server 2005. 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