web-dev-qa-db-ja.com

try-catchブロック内にストアドプロシージャを作成する

私はsqlserver 2014を使用しており、次のようにtry-catchブロック内にStoredProcedureを作成しようとしています。

BEGIN TRY   
  CREATE PROCEDURE [ammeghezi1] (@w INT) AS SELECT '' 
END TRY
BEGIN CATCH
  ...
END CATCH

次のエラーで実行に失敗します:Incorrect syntax near 'SELECT' Expecting EXTERNAL.
その後、spを次のように変更しました:CREATE PROCEDURE [ammeghezi1] (@w INT) AS BEGIN SELECT '' END(BEGIN-ENDブロックでspをカバー)、しかしエラーは変わりませんでした。 BEGIN TRYステートメントの後にGOも追加しましたが、最悪です。
TRY_CATCHブロック内にspを作成することは実用的ではないと結論しました。

これはTRY_CATCHブロック内にspを作成することも可能ですか?そしてどのように?

3
Rzassar

から - CREATE PROCEDUREドキュメント

CREATE PROCEDUREステートメントは、単一のバッチで他のTransact-SQLステートメントと組み合わせることはできません。

Try/catchが必要な場合は、動的SQLを使用してDDLを実行し、別のバッチになるようにする必要があります。

BEGIN TRY   
    DECLARE @CreateProcedureStatement nvarchar(MAX) =
N'CREATE PROCEDURE [ammeghezi1] (@w INT) AS SELECT ''''';
    EXEC sp_executesql  @CreateProcedureStatement;
END TRY
BEGIN CATCH
    THROW;
END CATCH
GO
6
Dan Guzman

興味深い質問ですが、ここでは悪い習慣を感じています(これはDBAの視点ではなく、SQL開発者の視点です)。どうしてそうするか?

プロシージャを作成する必要がある場合、それが存在しない場合は、単に その存在を確認する

IF EXISTS ( SELECT * 
            FROM   sysobjects 
            WHERE  id = object_id(N'[dbo].[MyProc]') 
                   and OBJECTPROPERTY(id, N'IsProcedure') = 1 )

これがどのように実行されるかのコンテキストは指定されていませんが、重要かもしれません。これがデプロイメントプロセスの一部である場合は、通常、例外(実行エラー)をバブルさせてSQLの外部で処理することをお勧めします。

ストアドプロシージャを動的SQLとして実行している間、私はそれに対してアドバイスをします。その作成を文字列として書き込むのは非常に難しく、ひ​​どく(読みづらく)見え、すべての解析エラーがランタイムに移動します。

4
Alexei