SQL Server 2008

Цель: Сгенерировать скрипты для создания sprocs, которые уже есть в БД. Должен быть один скрипт на файл.

Я знаю, что могу просто щелкнуть правой кнопкой мыши по базе данных и выбрать «Задачи> Создать сценарии», но это не создает сценария для sproc в нужном мне шаблоне.

Мне нужно, чтобы sproc был написан в том же шаблоне, который вы получаете, когда вы щелкаете правой кнопкой мыши sproc из проводника объектов и «Скрипт хранимой процедуры как> DROP and CREATE».

Это правда, что вы получаете аналогичную версию через «Задачи> Создать сценарии», но основное отличие заключается в том, что метод «Задачи> Создать сценарии» создает сценарий с помощью команды dbo.sp_executesql, потому что вы не можете вложить CREATE PROCEDURE внутри блока IF

Tasks> Generate производит следующее:

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

Любые идеи?

7
Justin Self 26 Авг 2011 в 20:26

3 ответа

Лучший ответ

Чтобы создать скрипт из 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

Ссылки:

5
8kb 27 Авг 2011 в 07:51

Вот как я бы это сделал (в 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;     
}

Я не упомянул обработку ошибок, правильный сборщик мусора и т. Д.

1
Aaron Bertrand 26 Авг 2011 в 21:47

Это сработало для меня:

Я изменил хранимую процедуру, чтобы сгенерировать скрипты для таких таблиц:

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 
0
Brian Webster 28 Окт 2012 в 03:19