web-dev-qa-db-ja.com

SQL Server Management Studio GUIによって返されるソースと同一のSQL Serverストアドプロシージャソースをプログラムで取得しますか?

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

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

繰り返しますが、SMSEを使用してSQL Server 2005を使用しています。 Visual Studio 8 2008を介したSMOの使用。

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

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

    使用[MY_DB] 
 GO 
/******オブジェクト:StoredProcedure [dbo]。[sp_mysp]スクリプト日付:01/21/2009 17:43:18 ***** */
 SET ANSI_NULLS ON 
 GO 
 SET QUOTED_IDENTIFIER ON 
 GO 
-============ ================================ 
-著者:
-日付の作成:
-説明:
-================================ ============ 
 ALTER PROCEDURE [dbo]。[sp_mysp] 

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

スクリプト日付の詳細が異なるものだけを手に入れたいと思います。 。 。

64
DWright
EXEC sp_helptext 'your procedure name';

これにより、ストアドプロシージャが長すぎる場合に切断されるINFORMATION_SCHEMAアプローチの問題を回避できます。

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

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

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

81

あなたはそれを手作業でコーディングする必要があります、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を使用して...

15
Sam Saffron

プログラムで言ったよね? 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;
11
Hunter

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

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

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

7
keithwarren7

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

5
BankZ

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

4
Chris Nava

Find and replaceを使用してcreate procedureを変更してprocedureを変更する代わりに、ドロップを使用することもできます。ドロップを一番上に置くと、テキスト検索が必要になります。

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

確かに存在する場合は、ドロップすることもできますが、お勧めしません。作成プロシージャはバッチ内の最初で唯一のステートメントである必要があるため、移動を忘れないでください。

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

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