67

SQL Server Management Studio でそのストアド プロシージャを右クリックして [変更] を選択したときのように、SQL Server 2005 からまったく同じストアド プロシージャ ソースをプログラムで取得する方法についての指針はありますか?

私は SMO を使用しようとしていますが、いくつかのテキストの違いがあります。プロシージャには常に ALTER ではなく CREATE があり、プログラムで取得しているバージョンで GO が欠落しているなど、ヘッダーにいくつかの違いがあります。これらを修正することはできますが、おそらくもっと良い方法がありますか?

ここでも、SQL Server 2005 で SMSE を使用しています。Visual Studio 8 2008 経由で SMO を使用します。

更新: ストアド プロシージャを取得する方法の基本を説明するいくつかの回答を得ました。私が探しているのは、GUI が生成するものと同一 (またはほぼ同一) のテキストを取得することです。

例: sp_mysp の場合、Management Studio で右クリックし、[変更] を選択します。これにより、次が生成されます。

    [MY_DB] を使用  
    行く  
    /***** オブジェクト: StoredProcedure [dbo].[sp_mysp] スクリプトの日付: 2009/01/21 17:43:18 ******/  
    ANSI_NULLS をオンに設定  
    行く  
    QUOTED_IDENTIFIER をオンに設定  
    行く  
    -- ==============================================
    -  著者:      
    -  日付を作成します:
    -  説明:
    -- ==============================================
    ALTER PROCEDURE [dbo].[sp_mysp]

プログラムで同じことを取得したいと思います (ヘッダーの GO と、それが ALTER PROCEDURE であることに注意してください。理想的には、取得したソースのプログラムによる修正を最小限に抑えてこれを取得したいと思います。

Script Date の詳細が異なるものだけを入手できれば幸いです。. .

4

9 に答える 9

83
EXEC sp_helptext 'your procedure name';

これにより、INFORMATION_SCHEMA アプローチの問題が回避され、ストアド プロシージャが長すぎると途切れてしまいます。

更新: David は、これは彼の sproc と同一ではないと書いています...おそらく、書式を維持するために行を「レコード」として返すためでしょうか? 結果をより「自然な」形式で表示したい場合は、最初に Ctrl-T を使用して (テキストとして出力)、入力したとおりに正確に出力する必要があります。これをコードで実行している場合、foreach を実行して結果をまったく同じ方法でまとめるのは簡単です。

更新 2: これにより、ソースに「ALTER PROCEDURE」ではなく「CREATE PROCEDURE」が提供されますが、代わりに「ALTER」を使用する方法はわかりません。些細なことですが、そうではありませんか?

更新 3: ソース管理システムで SQL DDL (データベース構造) を維持する方法についての詳細については、コメントを参照してください。それがまさにこの質問の鍵です。

于 2009-01-21T23:33:25.037 に答える
16

手作業でコーディングする必要があります。SQL プロファイラーは次のことを明らかにします。

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を使用すると、より簡単になります...

于 2009-01-22T00:04:53.413 に答える
12

あなたはプログラム的に言いましたよね?C# でいいと思います。SMO を試してみたが、期待どおりの結果が得られなかったとのことですが、これはおそらくあなたの要求には完全ではないでしょうが、ストアド プロシージャを再作成するために実行できる正当な SQL ステートメントをプログラムで読み取ることができます。必要なステートメントが含まれていない場合は、 の各文字列の後に がある可能性があるGOと想定できます。日付と時刻が記載されたコメントは得られないかもしれませんが、私の似たようなサウンドのプロジェクト (すべてを個別にバックアップする必要がある巨大な展開ツール) では、これはかなりうまく機能しています。作業したい以前のベースがあり、これを実行するための元のデータベースがまだある場合は、最初の努力を捨てて、この出力を再標準化することを検討します.StringCollectionGO

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;
于 2009-06-02T04:56:19.610 に答える
9

次の select ステートメントを使用して、定義全体を取得します。

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

SSMS やその他のツールがこれを読み込んで、CREATE を ALTER に変更するなど、必要に応じて変更を加えていると思います。私の知る限り、SQL はプロシージャの他の表現を格納しません。

于 2009-01-21T23:27:48.620 に答える
5

私はマークに同意します。出力をテキスト モードに設定してから、sp_HelpText 'sproc' に設定しました。簡単にするために、これを Crtl-F1 にバインドしています。

于 2009-01-21T23:43:21.103 に答える
4

データベース公開ウィザードは、コマンド ラインからスキーマ (およびその他のオブジェクト) をダンプできます。

于 2009-01-22T05:34:05.090 に答える
2

検索と置換を使用して作成プロシージャを変更してプロシージャを変更する代わりに、ドロップを使用することもできます。ドロップを一番上に配置すると、テキスト検索が必要になります。

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

そこにあると確信しているなら、あなたもそれを落とすことができると思いますが、私はそれをお勧めしません。createプロシージャはバッチの最初で唯一のステートメントである必要があるため、移動を忘れないでください。

または怠惰なアプローチ:

IF OBJECT_ID(N'sp_name') is not null
    DROP sp_name
GO
于 2012-02-03T13:34:24.037 に答える
-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();

注意事項:

  1. 接続文字列の USER に SP を変更する権限があることを確認してください
  2. スクリプト ファイルからすべてのGO,SET ANSI_NULLS XX,SET QUOTED_IDENTIFIERステートメントを削除します。(そうしないと、SqlCommand はエラーをスローします)。
于 2010-03-18T09:36:29.703 に答える