通过SQL脚本导出存储过程

时间:2011-07-25 13:53:13

标签: sql sql-server-2005 stored-procedures backup ssms

是:如何使用查询备份选定的存储过程

我想通过命令行(在SQL Server Management Studio中)备份200个存储过程中的10个。有一个简单的方法吗?

现在我正在使用Database-> Tasks-> Generate Scripts选项,它会引导我完成一系列对话框,我选择要导出的SP。我想让这个过程变得简单,所以我不必再重复一遍。

注意:通过导出我的意思是只在屏幕上打印它,这样我就可以将其复制并保存在文本文件中。

8 个答案:

答案 0 :(得分:10)

如何使用INFORMATION_SCHEMA.Routines?

DECLARE MY_CURSOR Cursor
FOR
SELECT r.Routine_Definition
FROM INFORMATION_SCHEMA.Routines r 
OPEN MY_CURSOR
    DECLARE @sproc VARCHAR(MAX) 
    FETCH NEXT FROM MY_CURSOR INTO @sproc
    WHILE (@@FETCH_STATUS <> -1)
    BEGIN
        IF (@@FETCH_STATUS <> -2)
        PRINT @sproc
        FETCH NEXT FROM MY_CURSOR INTO @sproc
    END
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR
GO

修改

听起来你可能想要这样的东西在结果集中包含LAST_ALTERED日期和定义。

SELECT
    r.LAST_ALTERED,
    r.ROUTINE_NAME,
    r.Routine_Definition
FROM INFORMATION_SCHEMA.Routines r 

答案 1 :(得分:4)

您可以使用以下查询选择所需的SP:

SELECT obj.Name as SPName,

modu.definition as SPDefinition,

obj.create_date as SPCreationDate

FROM sys.sql_modules modu

INNER JOIN sys.objects obj

ON modu.object_id = obj.object_id

WHERE obj.type = 'P'  AND obj.Name IN ('sp1','sp2', ect)

另请参阅:http://www.sqlservercurry.com/2009/03/list-all-stored-procedures-of-database.htmlhttp://www.sqlservercurry.com/2007/12/redirect-select-query-output-to-text.html

答案 2 :(得分:4)

以下SQL应该做你想要的。

SET NOCOUNT ON

DECLARE @procs AS TABLE( object_id INT
                        , definition NVARCHAR(MAX)
                        , uses_ansi_nulls BIT
                        , uses_quoted_identifier BIT
                        )
INSERT INTO @procs
SELECT m.object_id
     , m.definition
     , m.uses_ansi_nulls
     , m.uses_quoted_identifier
FROM sys.sql_modules AS m
INNER JOIN sys.objects AS o
    ON m.object_id = o.object_id
WHERE o.type = 'P'

--Change this part to suit your needs...
AND o.name IN ('sproc1'
              ,'sproc2'
              ,'sproc3'
              )
--Optionally filter by date?
--AND o.create_date >= '02/01/2012'


DECLARE @endStmt NCHAR(6)
      , @object_id INT
      , @definition NVARCHAR(MAX)
      , @uses_ansi_nulls BIT
      , @uses_quoted_identifier BIT
SELECT @object_id = MIN(object_id)
     , @endStmt = CHAR(13) + CHAR(10) + 'GO' + CHAR(13) + CHAR(10)
FROM @procs

WHILE ISNULL(@object_id,0) > 0
BEGIN
    SELECT @definition = definition
         , @uses_ansi_nulls = uses_ansi_nulls
         , @uses_quoted_identifier = uses_quoted_identifier
    FROM @procs

    IF @uses_ansi_nulls = 1
        PRINT 'SET ANSI_NULLS ON' + @endStmt
    ELSE
        PRINT 'SET ANSI_NULLS OFF' + @endStmt

    IF @uses_quoted_identifier = 1
        PRINT 'SET QUOTED_IDENTIFIER ON' + @endStmt
    ELSE
        PRINT 'SET QUOTED_IDENTIFIER OFF' + @endStmt

    IF LEN(@definition) <= 4000
        PRINT @definition 
    ELSE
    BEGIN
        DECLARE @crlf VARCHAR(2), @len BIGINT, @offset BIGINT, @part BIGINT
        SELECT @crlf = CHAR(13)+CHAR(10)
             , @len = LEN(@definition)
             , @offset = 1
             , @part = CHARINDEX(@crlf,@definition)-1

        WHILE @offset <= @len
        BEGIN
            PRINT SUBSTRING(@definition,@offset,@part)

            SET @offset = @offset + @part + LEN(@crlf)
            SET @part = CHARINDEX(@crlf,@definition,@offset)-@offset  
        END
    END

    PRINT @endStmt


    SELECT @object_id = MIN(object_id)
    FROM @procs
    WHERE object_id > @object_id
END

如果将上述SQL保存为名为BackUpSprocs.SQL的文件,则可以运行类似于以下内容的命令将输出发送到文件。

SQLCMD -E -S SQLSERVER_NAME -d DATABASE_NAME -i BackUpSprocs.SQL -o Sprocs.txt

答案 3 :(得分:2)

declare @S nvarchar(max) 

set @S = N''
select @S = @S + [definition] + 
                 nchar(13) + nchar(10) + 
                 N'GO' + 
                 nchar(13) + nchar(10)
from sys.sql_modules as m
  inner join sys.objects as o
    on m.object_id = o.object_id
where o.create_date > '20120101' and
      o.name in ('Proc1', 'Proc2', 'ProcN')

select @S
for xml path('')

单击结果窗格中的链接以查看整个脚本。

答案 4 :(得分:0)

SELECT SO.Name as Name, 

SM.definition as SPDefinition, 

obj.create_date as CreationDate 

FROM sys.sql_modules SM

INNER JOIN sys.objects SO

ON SM.object_id = SO.object_id 

WHERE SO.type = 'P'  AND SO.create_date >= '01-01-2012'

检查一下。这可能会对你有帮助。

答案 5 :(得分:0)

不是SQL方式,但我认为您可以使用autoit或{{3自动化您的数据库 - &gt;任务 - &gt;生成脚本选项/ ...更多步骤或者其他一些GUI测试工具。

我尝试了一些Sikuli用于网络,但对我来说这并不是100%可靠。

  

AutoIt v3是一款免费的类似BASIC的脚本语言   自动化Windows GUI和常规脚本。

答案 6 :(得分:0)

我编辑了MyItchyChin的脚本,因为我发现了它的一些缺陷。当@part&lt;时,它会无限循环。 0并且无法正确打印关闭过程代码的“END”关键字(“创建过程...作为开始...... 结束”)。我也做了其他一些小改动。我的问题现在解决了!非常感谢MyItchyChin的初始脚本。

Obs:我在SQL Server 2008 R2中使用此脚本。该脚本还可用于编写脚本函数。

 SET NOCOUNT ON

DECLARE @procs AS TABLE( nome varchar(200),object_id INT
                        , definition NVARCHAR(MAX)
                        , uses_ansi_nulls BIT
                        , uses_quoted_identifier BIT
                        )
INSERT INTO @procs
SELECT o.name
     ,m.object_id
     , m.definition
     , m.uses_ansi_nulls
     , m.uses_quoted_identifier
FROM sys.sql_modules AS m
INNER JOIN sys.objects AS o
    ON m.object_id = o.object_id
WHERE 1=1
--and o.type = 'P'
AND o.name IN ('proc1')



DECLARE @endStmt NCHAR(6)
      , @object_id INT
      , @definition NVARCHAR(MAX)
      , @uses_ansi_nulls BIT
      , @uses_quoted_identifier BIT

DECLARE @crlf VARCHAR(2), @len BIGINT, @offset BIGINT, @part BIGINT

SELECT @object_id = MIN(object_id)
     , @endStmt = CHAR(13) + CHAR(10) + 'GO' + CHAR(13) + CHAR(10)
FROM @procs

declare c cursor for SELECT definition
,  uses_ansi_nulls
,  uses_quoted_identifier
FROM @procs
order by nome asc

open c
fetch next from c into @definition,@uses_ansi_nulls,@uses_quoted_identifier

while @@fetch_status<>-1
begin
    IF @uses_ansi_nulls = 1
        PRINT 'SET ANSI_NULLS ON' + @endStmt;
    ELSE
        PRINT 'SET ANSI_NULLS OFF' + @endStmt;

    IF @uses_quoted_identifier = 1
        PRINT 'SET QUOTED_IDENTIFIER ON' + @endStmt;
    ELSE
        PRINT 'SET QUOTED_IDENTIFIER OFF' + @endStmt;

    --PRINT @definition;

    IF LEN(@definition) <= 4000
        PRINT @definition
    ELSE
    BEGIN

        SELECT @crlf = CHAR(13)+CHAR(10)
             , @len = LEN(@definition)
             , @offset = 1
             , @part = CHARINDEX(@crlf,@definition)-1

        WHILE @offset <= @len AND @part>=0
        BEGIN

            --PRINT @offset
            --PRINT @part
            --PRINT LEN(@crlf)
            --PRINT @len

            PRINT SUBSTRING(@definition,@offset,@part)

            SET @offset = @offset + @part + LEN(@crlf)
            SET @part = CHARINDEX(@crlf,@definition,@offset)-@offset

            --PRINT @offset
            --PRINT @part
            --PRINT @len

            IF @part < 0 
            PRINT SUBSTRING(@definition,@offset,100)
        END
    END

    PRINT @endStmt;


fetch next from c into @definition,@uses_ansi_nulls,@uses_quoted_identifier
end
close c
deallocate c

答案 7 :(得分:0)

我创建了以下过程,通过所有SP和视图,特别是DB(可以扩展到Functions,...),并将每个代码脚本逐个存储到TXT文件中。在MS SQL 2008 R2和2014上测试

第一部分将SP和Views的所有脚本插入Temp表。然后使用BCP实用程序。如果您希望可以使用导出SSIS包而不是SP,就像我在本例中所做的那样。

DECLARE  @File_name AS VARCHAR(255)
        ,@Folder_path AS VARCHAR(255)
        ,@File_Path_Name AS VARCHAR(255)
        ,@CMD AS VARCHAR(8000)

IF OBJECT_ID('tempdb..#TEMP_AA') IS NOT NULL DROP TABLE #TEMP_AA;
SELECT 
 T1.NAME AS ObjectName
,T1.type AS ObjectType
,STUFF(((SELECT ' ' + T.[TEXT]
         FROM (SELECT SC.[id],SC.colid,SC.[TEXT]
               FROM SYSCOMMENTS sc
               ) AS T
         WHERE T.[id] = T1.[id]
         ORDER BY T.colid
         FOR XML PATH(''),TYPE
         ).value('.[1]', 'NVARCHAR(MAX)')
         ), 1, 1, '')
 AS ObjectText
INTO #TEMP_AA
FROM SYSOBJECTS AS T1
WHERE 1=1
  AND T1.type IN ('P', 'V') /* Procedures and Views*/
  AND NOT T1.[name] LIKE 'dt_%'

循环通过临时表创建文件名,前缀为P_或V_,后缀为日期,格式为YYYYMMDD:

-- Exporting Scripts one by one into TXT files
WHILE (SELECT TOP 1 objectName FROM #TEMP_AA) IS NOT NULL
BEGIN
    SELECT TOP 1 
    @File_name = RTRIM(LTRIM(ObjectType)) + '_' + ObjectName +'_' + REPLACE(CAST(CAST(GETDATE()AS DATE) AS VARCHAR),'-','')
    FROM #TEMP_AA;

    IF OBJECT_ID('tempdb..##TEMP_BB') IS NOT NULL DROP TABLE ##TEMP_BB;
    CREATE TABLE ##TEMP_BB (ObjectText VARCHAR(MAX));
    INSERT INTO ##TEMP_BB
    SELECT TOP 1 ObjectText
    FROM #TEMP_AA;

    --'Setting File name'
    SET @Folder_Path = 'C:\AAAA\'
    SET @File_Path_Name = @Folder_Path + @File_name + '.txt'
    SET @CMD ='BCP ##TEMP_BB OUT "'+@File_Path_Name+'" -T -c -t "Your Server"'
     -- 'Output via BCP into TXT file'
    EXEC xp_cmdshell @CMD;

    --Delete Line From temp which has been procese already
    WITH  CTE AS (SELECT TOP 1 *  FROM  #TEMP_AA)
    DELETE FROM CTE;
END