【问题标题】:t-sql stored procedure create scriptst-sql 存储过程创建脚本
【发布时间】:2011-03-18 13:51:56
【问题描述】:

我有一堆存储过程名称。我想为每个存储过程导出创建脚本。最好的方法是什么?

现在我在 SSMS 中手动选择存储过程并选择 "Script stored procedure as -> Drop and Create to"。这似乎很乏味。我希望有更好的方法来处理这个问题。谢谢。

【问题讨论】:

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


    【解决方案1】:

    您可以在对象资源管理器中右键单击数据库并执行任务 > 生成脚本。

    这允许您选择一大堆要编写脚本的对象(例如表、视图、存储过程),您可以将它们存储到一个大 SQL 文件中,或者每个对象一个 SQL 文件中。效果真的很好!

    更新:如果您想在 SQL Server Management Studio 应用程序中执行此操作,您可以使用此 SQL 脚本来查找存储的过程及其定义 - 但是您不能让 SQL Server Mgmt Studio 编写将文件输出到磁盘,这不起作用 - 但您可以将结果复制到例如Excel。

    SELECT 
        pr.name ,
        pr.type_desc ,
        pr.create_date ,
        mod.definition
    FROM sys.procedures pr
    INNER JOIN sys.sql_modules mod ON pr.object_id = mod.object_id
    WHERE pr.Is_MS_Shipped = 0
    

    【讨论】:

    • 谢谢马克。实际上,我有一堆 SSRS 报告和一个提取存储过程名称的实用程序。由于会频繁地出现更多此类报告,因此我正在考虑一个 t-sql 脚本,它可以获取存储过程列表并生成一个脚本文件。这可能吗?
    • 谢谢。正是我想要的。
    【解决方案2】:

    要编写出所有符合特定条件的脚本,您可以使用如下所示的内容。

    DECLARE @t VARCHAR(max) = '';
    SELECT @t = @t +
     'If OBJECT_ID(''' + QUOTENAME(OBJECT_SCHEMA_NAME(object_id)) + '.' +  QUOTENAME(OBJECT_NAME(object_id)) + ''',''p'') IS NOT NULL
        DROP PROCEDURE ' + QUOTENAME(OBJECT_SCHEMA_NAME(object_id)) + '.' +  QUOTENAME(OBJECT_NAME(object_id)) + '
    GO
    
    SET ANSI_NULLS '
                + CASE
                    WHEN uses_ansi_nulls = 1 THEN 'ON'
                    ELSE 'OFF'
                  END
                + '
    GO
    
    SET QUOTED_IDENTIFIER '
                + CASE
                    WHEN uses_quoted_identifier = 1 THEN 'ON'
                    ELSE 'OFF'
                  END
                + '
    GO
    
    ' + definition + ' 
    GO
    
    '
    FROM   [sys].[sql_modules]
    WHERE  OBJECTPROPERTY (object_id,'IsProcedure' )=1
           AND OBJECT_NAME(object_id) LIKE '%some_patttern%'
    
    
    /*Stops the long text from getting truncated in SSMS*/
    SELECT @t AS [processing-instruction(x)]
    FOR XML PATH('') 
    

    【讨论】:

    • 这是如何工作的?我需要将@t 设置为逗号分隔的存储过程名称列表吗?
    • @stack - 不,但你可以去掉LIKE 并使用in
    • 太棒了,正是我需要的,不需要鼠标点击。
    • 除了在某个日期之后创建的 SP 之外,如何做同样的事情?我找到了一种从sys.objects 获取 SP 列表的方法,但sys.sql_modules 中没有日期列...
    • 很好的解决方案。将此脚本添加到我的工具箱中
    【解决方案3】:

    如果您选择查看 --> 摘要

    然后从对象资源管理器中单击“存储过程”,它将为您提供所有存储过程的列表,您可以 Ctrl/Shift 选择(选择多个)。 然后从那里您可以一次创建所有放置脚本,然后创建所有创建脚本。这是我在 SSMS 中发现的众多怪癖之一。

    注意:另一个简洁的功能是过滤器选项,允许您轻松过滤存储/表过程。只需右键单击对象资源管理器即可调出菜单。

    【讨论】:

    • 感谢您告知过滤器功能。给我点赞。
    【解决方案4】:

    这样的事情会帮助你。

    使用动态 sql 和游标,您可以生成脚本,每个脚本都在一个单独的文件中,扩展名为 .sql。

    此脚本将为所有在 IN 子句中提及名称的过程生成脚本:

    DECLARE @name varchar(100)
    DECLARE @Definition varchar(max)
    DECLARE @sql varchar(300)
    DECLARE @schema varchar(10)
    CREATE TABLE TEMPTABLE (ID INT IDENTITY(1,1), def varchar(max))
    DECLARE script CURSOR  
    FOR
    SELECT OBJECT_NAME(SYS.SQL_MODULES.OBJECT_ID), [DEFINITION] FROM SYS.SQL_MODULES 
    INNER JOIN SYS.OBJECTS ON SYS.OBJECTS.OBJECT_ID = SYS.SQL_MODULES.OBJECT_ID WHERE SYS.OBJECTS.TYPE='P'
    --AND [NAME] IN('SOME PROC 1','SOME PROC 2','SOME PROC 3','SOME PROC 4') --<------ Mention Proc names you want to generate scripts for
    OPEN script
    FETCH NEXT FROM script INTO @name, @Definition
    WHILE @@FETCH_STATUS = 0 
    BEGIN
      FETCH NEXT FROM script INTO @name, @Definition
      SET @schema = (select SYS.SCHEMAS.[NAME] from SYS.OBJECTS 
                     INNER JOIN SYS.SCHEMAS ON SYS.OBJECTS.SCHEMA_ID = SYS.SCHEMAS.SCHEMA_ID 
                     WHERE SYS.OBJECTS.[NAME]='' + @name + '')
      SET @sql = 'IF EXISTS (SELECT * FROM ' + (@schema) +
                 '.PROCEDURES WHERE [NAME] = ''' + @name + ''')' + CHAR(10)
      SET @sql = @sql + 'DROP PROCEDURE ' + @schema + '.' + @name + CHAR(10) + 'GO' + CHAR(10)
      PRINT @sql
      INSERT INTO TEMPTABLE VALUES(@sql + @definition)
      SET @Sql = ('BCP "SELECT TOP 1 def FROM TEMPTABLE ORDER BY ID DESC" queryout "D:\' + @name + '.sql" -c -T')
      EXEC XP_CmdShell @Sql  --<---- Export to file
    END 
    CLOSE script
    DEALLOCATE script
    SELECT * FROM TEMPTABLE  --<----------- Optional
    DROP TABLE TEMPTABLE
    

    【讨论】:

      【解决方案5】:

      您可以查看 sp_helptext,了解如何利用它来创建脚本。

      【讨论】:

        【解决方案6】:

        Visual Studio 2008 Database Professional Edition 和 Visual Studio 2010 Professional(及更高版本)支持 SQL Server 2005/2008 的特殊项目类型。这些项目支持自动创建更改脚本,包含当前项目和指定目标数据库之间的所有更改。

        AFAIK RedGate 也提供了一些类似的工具,不过,我对它们没有任何经验。

        【讨论】:

          【解决方案7】:

          以下将为一组存储过程名称生成脚本。脚本将保存为一系列 .sql 文件。将要编写脚本的过程的名称插入@Table。

          -- Script Multiple SPROC as drop and create
          
          -- SPROCS to script
          DECLARE @Table TABLE (Name VARCHAR(MAX));
          INSERT INTO @Table (Name) VALUES ('StoredProcedure1'), ('StoredProcedure2')
          
          -- Drop TempTable if extant: http://stackoverflow.com/questions/659051/check-if-a-temporary-table-exists-and-delete-if-it-exists-before-creating-a-temp
          IF OBJECT_ID('tempdb..##Temp') IS NOT NULL DROP TABLE dbo.##Temp
          
          -- Loop through SPROCs    
          -- Cursor: https://www.mssqltips.com/sqlservertip/1599/sql-server-cursor-example/
          -- Substring: http://stackoverflow.com/questions/4662496/trim-left-characters-in-sql-server
          DECLARE @item VARCHAR(MAX); -- SPROC Name
          DECLARE db_cursor CURSOR FOR  
          SELECT Name FROM @Table WHERE 1=1
          
          OPEN db_cursor   
          FETCH NEXT FROM db_cursor INTO @item
          
          WHILE @@FETCH_STATUS = 0   
          BEGIN
              -- Execute
              -- Print to file using Temp Table: http://stackoverflow.com/questions/10568975/can-i-specify-an-input-sql-file-with-bcp
              -- Script SPROC via XML: http://stackoverflow.com/a/3292693/5301903
              -- ANSI_NULLS and QUOTED_IDENTIFIER retain current settings.
              -- Prepare Temp Table
              SELECT
          'IF EXISTS(SELECT * FROM sys.procedures WHERE Name = '''+Object_name(object_id)+''')
              DROP PROCEDURE [dbo].['+Object_name(object_id)+']
          GO
          
          SET ANSI_NULLS '+CASE WHEN CAST(ISNULL(OBJECTPROPERTYEX(object_id,N'ExecIsAnsiNullsOn'),0) AS bit) = 1 THEN 'ON' ELSE 'OFF' END+'
          GO
          
          SET QUOTED_IDENTIFIER '+CASE WHEN CAST(ISNULL(OBJECTPROPERTYEX(object_id,N'ExecIsQuotedIdentOn'),0) AS bit) = 1 THEN 'ON' ELSE 'OFF' END+'
          GO
          
          ' + definition + ' 
          GO' AS Text
          INTO dbo.##Temp
          FROM [sys].[sql_modules] 
          WHERE  1=1
          --AND OBJECTPROPERTY (object_id,'IsProcedure' )=1
          --AND OBJECTPROPERTY (object_id,'IsTable' )=1
          --AND Object_name(object_id) LIKE @name
          AND Object_name(object_id) = @item
          
              -- Print to text https://social.msdn.microsoft.com/Forums/en-US/71aefd98-ee46-48fe-a129-60791c583555/output-results-to-text-file-using-tsql?forum=transactsql
              DECLARE @CMD VARCHAR(1000) = 'bcp "SELECT * FROM ##Temp" queryout C:\temp\'+@item+'.sql -c -T -S '+ @@servername
              EXECUTE Master.dbo.xp_CmdShell  @Cmd
          
              -- Clean up
              DROP TABLE dbo.##Temp
          
              -- End Execute
              FETCH NEXT FROM db_cursor INTO @item
          END   
          
          CLOSE db_cursor   
          DEALLOCATE db_cursor
          

          【讨论】:

            【解决方案8】:
            C:\>BCP "Select '--'+pr.name,
                pr.type_desc, pr.create_date, pr.modify_date, CHAR(13)+mod.definition
                from DATABASE_NAME.sys.objects pr
                INNER JOIN DATABASE_NAME.sys.sql_modules mod ON pr.object_id = mod.object_id
                where type='p'" queryout "C:/output.sql" -c -T -S SERVER_NAME
            

            从命令提示符处执行...它将在一个文件中返回所有存储过程,并带有带有创建/修改日期的 SP 的时间戳

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2018-10-03
              • 2013-05-28
              • 2013-05-02
              • 2018-04-08
              • 2011-08-03
              • 1970-01-01
              • 2021-05-02
              相关资源
              最近更新 更多