首页 文章

以编程方式检索与SQL Server Management Studio gui返回的源相同的SQL Server存储过程源?

提问于
浏览
62

有关如何以编程方式从SQL Server 2005获取完全相同的存储过程源的任何指针,就像我在SQL Server Management Studio中右键单击该存储过程并选择修改一样?

我正在尝试使用SMO,但存在一些文本差异 . 该过程始终具有CREATE,而不是ALTER,并且标头中存在一些差异,例如在我以编程方式获取的版本中缺少GO . 我可以解决这些问题,但也许还有更好的方法吗?

我再次使用SMSE在SQL Server 2005中 . 通过Visual Studio 8 2008使用SMO .

Update :得到一些答案,告诉我们如何检索存储过程的基础知识 . 我正在寻找的是检索与GUI生成的文本相同(或几乎相同)的文本 .

示例:对于sp_mysp,在Management Studio中单击鼠标右键,选择“修改” . 这会产生:

USE [MY_DB]  
    GO  
    /****** Object:  StoredProcedure [dbo].[sp_mysp]    Script Date: 01/21/2009 17:43:18 ******/  
    SET ANSI_NULLS ON  
    GO  
    SET QUOTED_IDENTIFIER ON  
    GO  
    -- =============================================
    -- Author:      
    -- Create date: 
    -- Description: 
    -- =============================================
    ALTER PROCEDURE [dbo].[sp_mysp]

我想以编程方式获得相同的东西(注意 Headers 中的GO,以及它是一个更改程序的事实 . 理想情况下,我希望通过最小程序修复所检索的源来实现此目的 .

我很乐意在Script Date细节中得到不同的东西 . . .

8 回答

  • 15
    EXEC sp_helptext 'your procedure name';
    

    这避免了INFORMATION_SCHEMA方法的问题,其中如果存储过程太长则存储过程被切断 .

    更新:David写道,这与他的sproc并不完全相同......也许是因为它将这些行作为“记录”返回以保留格式?如果您想以更“自然”的格式查看结果,可以先使用Ctrl-T(输出为文本),然后将其打印出来,就像输入它一样 . 如果你在代码中这样做,那么做一个foreach以完全相同的方式组合你的结果是微不足道的 .

    更新2:这将为源提供“创建过程”而不是“更改过程”,但我知道无法使用“ALTER”代替 . 然而,有点琐碎的事情不是吗?

    更新3:有关如何在源代码管理系统中维护SQL DDL(数据库结构)的更多信息,请参阅注释 . 这确实是这个问题的关键 .

  • 11

    您必须手动编写代码,SQL Profiler会显示以下内容 .

    SMSE在生成语句时执行相当长的查询字符串 .

    以下查询(或其中的某些内容)用于提取文本:

    SELECT
    NULL AS [Text],
    ISNULL(smsp.definition, ssmsp.definition) AS [Definition]
    FROM
    sys.all_objects AS sp
    LEFT OUTER JOIN sys.sql_modules AS smsp ON smsp.object_id = sp.object_id
    LEFT OUTER JOIN sys.system_sql_modules AS ssmsp ON ssmsp.object_id = sp.object_id
    WHERE
    (sp.type = N'P' OR sp.type = N'RF' OR sp.type='PC')and(sp.name=N'#test___________________________________________________________________________________________________________________00003EE1' and SCHEMA_NAME(sp.schema_id)=N'dbo')
    

    它返回纯CREATE,然后在某处的代码中用ALTER替换 .

    SET ANSI NULL内容以及GO语句和日期都是前缀 .

    使用sp_helptext,更简单...

  • -2

    你以编程方式说,对吗?我希望C#没问题 . 我知道你说过你尝试过SMO而且它并不适合你的请求,但它会以编程方式读出你可以运行以重新创建存储过程的合法SQL语句 . 如果它没有你想要的 GO 语句,你可以假设 StringCollection 中的每个字符串都可以有 GO . 你可能没有得到日期和时间的评论,但在我类似的声音项目(大屁股部署工具,必须单独备份所有内容),这已经做得相当不错 . 如果你有一个你想要工作的先前基础,并且你仍然有原始数据库来运行它,我会考虑抛弃最初的努力并重新计算这个输出 .

    using System.Data.SqlClient;
    using Microsoft.SqlServer.Management.Common;
    using Microsoft.SqlServer.Management.Smo;
    …
    string connectionString = … /* some connection string */;
    ServerConnection sc = new ServerConnection(connectionString);
    Server s = new Server(connection);
    Database db = new Database(s, … /* database name */);
    StoredProcedure sp = new StoredProcedure(db, … /* stored procedure name */);
    StringCollection statements = sp.Script;
    
  • 79

    使用以下select语句获取所有完整定义:

    select ROUTINE_DEFINITION from INFORMATION_SCHEMA.ROUTINES Where ROUTINE_NAME='someprocname'

    我的猜测是SSMS和其他工具读出来并在必要时进行更改,例如将CREATE更改为ALTER . 据我所知,SQL存储不是该过程的其他表示

  • 7

    我同意马克的观点 . 我将输出设置为文本模式,然后将sp_HelpText设置为“sproc” . 我把它绑在Crtl-F1上让它变得简单 .

  • 4

    Databse Publishing Wizard可以从命令行转储模式(和其他对象) .

  • 5

    我只想注意,不是使用find和replace来改变创建过程以改变过程,你也可以使用drop,你可以把它放在顶部,它确实需要文本搜索 .

    IF exists (SELECT * FROM sys.objects 
            WHERE object_id = OBJECT_ID(N'sp_name')
                and type in ('P','V') --procedure or view
            )
        DROP sp_name
    GO
    

    如果你确定它在那里,我猜你也可以放弃它,但我不建议这样做 . 不要忘记go,因为create procedure必须是批处理中的第一个也是唯一的语句 .

    或懒惰的方法:

    IF OBJECT_ID(N'sp_name') is not null
        DROP sp_name
    GO
    
  • 2

    改变一个存储过程,这是C#代码:

    SqlConnection con = new SqlConnection("your connection string");
    con.Open();
    cmd.CommandType = System.Data.CommandType.Text;
    string sql = File.ReadAllText(YUOR_SP_SCRIPT_FILENAME);
    cmd.CommandText = sql;   
    cmd.Connection = con;
    cmd.ExecuteNonQuery();
    con.Close();
    

    注意事项:

    • 确保连接字符串中的USER有权更改SP

    • 从脚本文件中删除所有 GO,SET ANSI_NULLS XX,SET QUOTED_IDENTIFIER 语句 . (如果不这样,SqlCommand将抛出错误) .

相关问题