Programmatically retrieve SQL Server stored procedure source that is identical to the source returned by the SQL Server Management Studio gui?

后端 未结 9 1888
孤独总比滥情好
孤独总比滥情好 2020-11-30 20:38

Any pointers on how I can programmatically get exactly the identical stored procedure source from SQL Server 2005, as when I right-click on that stored procedure in SQL Serv

相关标签:
9条回答
  • 2020-11-30 21:03

    Use the following select statement to get all the whole definition:

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

    my guess is that SSMS and other tools read this out and make changes where necessary such as changing CREATE to ALTER. As far as I know SQL stores not other representations of the procedure

    0 讨论(0)
  • 2020-11-30 21:06
    EXEC sp_helptext 'your procedure name';
    

    This avoids the problem with INFORMATION_SCHEMA approach wherein the stored procedure gets cut off if it is too long.

    Update: David writes that this isn't identical to his sproc...perhaps because it returns the lines as 'records' to preserve formatting? If you want to see the results in a more 'natural' format, you can use Ctrl-T first (output as text) and it should print it out exactly as you've entered it. If you are doing this in code, it is trivial to do a foreach to put together your results in exactly the same way.

    Update 2: This will provide the source with a "CREATE PROCEDURE" rather than an "ALTER PROCEDURE" but I know of no way to make it use "ALTER" instead. Kind of a trivial thing, though, isn't it?

    Update 3: See the comments for some more insight on how to maintain your SQL DDL (database structure) in a source control system. That is really the key to this question.

    0 讨论(0)
  • 2020-11-30 21:16

    I just want to note that instead of using find and replace to change create procedure to alter procedure, you are just as well to use a drop, you can put it right at the top and it does require text searching.

    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
    

    If you are sure it's there, I guess you could just drop it too, but I wouldn't recommend that. Don't forget the go, since create procedure must be the first and only statement in a batch.

    Or the lazy approach:

    IF OBJECT_ID(N'sp_name') is not null
        DROP sp_name
    GO
    
    0 讨论(0)
  • 2020-11-30 21:19

    You said programmatically, right? I hope C# is ok. I know you said that you tried SMO and it didn't quite do what you wanted, so this probably won't be perfect for your request, but it will programmatically read out legit SQL statements that you could run to recreate the stored procedure. If it doesn't have the GO statements that you want, you can probably assume that each of the strings in the StringCollection could have a GO after it. You may not get that comment with the date and time in it, but in my similar sounding project (big-ass deployment tool that has to back up everything individually), this has done rather nicely. If you have a prior base that you wanted to work from, and you still have the original database to run this on, I'd consider tossing the initial effort and restandardizing on this output.

    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;
    
    0 讨论(0)
  • 2020-11-30 21:20

    The Databse Publishing Wizard can dump the schema (and other objects) from the command line.

    0 讨论(0)
  • 2020-11-30 21:24

    You will have to hand code it, SQL Profiler reveals the following.

    SMSE executes quite a long string of queries when it generates the statement.

    The following query (or something along its lines) is used to extract the text:

    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')
    

    It returns the pure CREATE which is then substituted with ALTER in code somewhere.

    The SET ANSI NULL stuff and the GO statements and dates are all prepended to this.

    Go with sp_helptext, its simpler ...

    0 讨论(0)
提交回复
热议问题