SQL Server 2008
目标:生成用于创建数据库中已有的sprocs的脚本。每个文件必须是一个脚本。
我知道我可以直接右键单击数据库和'Tasks> Generate Scripts',但这不会在我想要的模板中编写sproc脚本。
我需要在右键单击对象资源管理器中的sproc并将“存储过程与脚本存储为> DROP和CREATE”时获得的相同模板中编写脚本。
通过“任务>生成脚本”获得类似版本的确是如此,但主要区别在于“任务>生成脚本”方法通过dbo.sp_executesql
命令创建脚本,因为您无法嵌套CREATE PROCEDURE
1}}在IF
块内
任务>生成产生这个:
USE someDB
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'somesproc') AND type in (N'P', N'PC'))
DROP PROCEDURE someSproc
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'someSproc') AND type in (N'P', N'PC'))
BEGIN
EXEC dbo.sp_executesql @statement = N'-- =============================================
CREATE PROCEDURE
AS
BEGIN
END
'
END
GO
但是我需要这个(从右键单击sproc中找到):
USE someDB
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'someSproc') AND type in (N'P', N'PC'))
DROP PROCEDURE someSproc
GO
USE someDB
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE someSproc
AS
BEGIN
SET NOCOUNT ON;
END
GO
有什么想法吗?
答案 0 :(得分:5)
为了从SSMS创建脚本......
第1步 - 创建脚本存储过程:
IF EXISTS (
SELECT *
FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[usp_ScriptProcedure]')
AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[usp_ScriptProcedure]
GO
CREATE PROCEDURE [dbo].[usp_ScriptProcedure] (
@ObjectID INT,
@Name NVARCHAR(128),
@SchemaID INT
)
AS
DECLARE
@code VARCHAR(MAX),
@newLine CHAR(2)
SET @newLine = CHAR(13) + CHAR(10)
SET @code =
'USE [' + DB_NAME() + ']' + @newLine + 'GO' + @newLine + @newLine
+ 'IF EXISTS (SELECT * FROM sys.objects WHERE object_id = '
+ 'OBJECT_ID(N''[' + SCHEMA_NAME(@schemaID) + '].[' + @Name + ']'') '
+ 'AND type IN (N''P'', N''PC''))' + @newLine
+ 'DROP PROCEDURE [' + SCHEMA_NAME(@schemaID) + '].[' + @name + ']'
+ @newLine + @newLine + 'SET ANSI_NULLS ON' + @newLine + 'GO'
+ @newLine + @newLine + 'SET QUOTED_IDENTIFIER ON' + @newLine + 'GO'
+ @newLine + @newLine
+ OBJECT_DEFINITION(@ObjectID) + @newLine + 'GO'
+ @newLine + @newLine + 'SET ANSI_NULLS OFF' + @newLine + 'GO'
+ @newLine + @newLine + 'SET QUOTED_IDENTIFIER OFF' + @newLine + 'GO'
WHILE @code <> ''
BEGIN
PRINT LEFT(@code,8000)
SET @code = SUBSTRING(@code, 8001, LEN(@code))
END
GO
第2步 - 启用xp_cmdshell
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
步骤3 - 运行下面的脚本(确保设置服务器名称和文件夹目的地)
DECLARE
@name sysname,
@objID int,
@schemaID int,
@cmd varchar(1000),
@folder varchar(128),
@server varchar(128)
SET @server = 'MSSQL'
SET @folder = 'C:\Scripts'
DECLARE procs CURSOR FOR
SELECT name, object_id, schema_id
FROM sys.procedures
WHERE is_ms_shipped = 0
ORDER BY [name]
OPEN procs
FETCH NEXT FROM procs
INTO @name, @objID, @schemaID
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = 'sqlcmd -S .\' + @server + ' -d ' + DB_NAME()
+ ' -Q "EXEC usp_ScriptProcedure '
+ CONVERT(VARCHAR(20), @objID) + ', N'''
+ @name + ''', ' + CONVERT(VARCHAR(20), @schemaID)
+ '" > ' + @folder + '\' + @name + '.sql'
EXEC xp_cmdshell @cmd
FETCH NEXT FROM procs
INTO @name, @objID, @schemaID
END
CLOSE procs
DEALLOCATE procs
参考文献:
答案 1 :(得分:1)
以下是我将如何做到这一点(在PowerShell中,而不是通过Management Studio):
$server = "GREENLANTERN\SQL2008R2" # server
$database = "AdventureWorks" # database
$folder = "C:\target\" # output folder
$conn_string = "Data Source=$server;Initial Catalog=$database;Integrated Security=SSPI"
$conn = new-object System.Data.SqlClient.SqlConnection($conn_string);
$conn.open();
$query = "SELECT
n = QUOTENAME(OBJECT_SCHEMA_NAME([object_id]))
+ '.' + QUOTENAME(name),
d = OBJECT_DEFINITION([object_id]),
f = OBJECT_SCHEMA_NAME([object_id])
+ '_' + name
FROM " + $database + ".sys.procedures;";
$command = new-object System.Data.SqlClient.SqlCommand $query, $conn
$reader = $command.ExecuteReader();
while ($reader.Read())
{
$procname = $reader.GetValue(0);
$crscript = $reader.GetValue(1);
$filename = $reader.GetValue(2);
$output = " USE [$database];
GO
IF EXISTS
(
SELECT 1
FROM sys.procedures
WHERE [object_id] = OBJECT_ID($procname)
)
BEGIN
DROP PROCEDURE $procname;
END
GO
$crscript
GO";
$file = "$folder$filename.sql";
$output | out-file $file; #might need -encoding ASCII;
}
我遗漏了错误处理,正确的GC等等。
答案 2 :(得分:0)
这对我有用:
我修改了存储过程,为这样的表生成脚本:
DECLARE tabls CURSOR FOR
SELECT name, object_id, schema_id
FROM sys.Tables
WHERE is_ms_shipped = 0
ORDER BY [name]
OPEN tabls
FETCH NEXT FROM tabls
INTO @name, @objID, @schemaID
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = 'sqlcmd -S .\' + @server + ' -d ' + DB_NAME()
+ ' -Q "EXEC usp_ScriptProcedure '
+ CONVERT(VARCHAR(20), @objID) + ', N'''
+ @name + ''', ' + CONVERT(VARCHAR(20), @schemaID)
+ '" > ' + @folder_Tbl + '\' + @name + '.sql'
EXEC xp_cmdshell @cmd
FETCH NEXT FROM tabls
INTO @name, @objID, @schemaID
END
CLOSE tabls
DEALLOCATE tabls