使用DROP和CREATE一次编写所有Sprocs脚本

时间:2011-08-26 16:26:32

标签: sql-server tsql sql-server-2008

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

有什么想法吗?

3 个答案:

答案 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