SQL Server でストアド プロシージャを条件付きで作成するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/55506

  •  09-06-2019
  •  | 
  •  

質問

統合戦略の一環として、データベースを更新するために実行される SQL スクリプトがいくつかあります。これらすべてのスクリプトが最初に行うことは、実行する必要があるかどうかを確認することです。例:

if @version <> @expects
    begin
        declare @error varchar(100);
        set @error = 'Invalid version. Your version is ' + convert(varchar, @version) + '. This script expects version ' + convert(varchar, @expects) + '.';
        raiserror(@error, 10, 1);
    end
else
    begin
        ...sql statements here...
    end

よく働く!ストアド プロシージャを追加する必要がある場合を除きます。「create proc」コマンドは、SQL コマンドのバッチ内の唯一のコマンドである必要があります。IF ステートメントに「create proc」を入れると、次のエラーが発生します。

'CREATE/ALTER PROCEDURE' must be the first statement in a query batch.

ああ!スクリプトに CREATE PROC コマンドを入れて、必要な場合にのみ実行するにはどうすればよいですか?

役に立ちましたか?

解決

私が思いついたのは次のとおりです。

次のように EXEC() でラップします。

if @version <> @expects
    begin
        ...snip...
    end
else
    begin
        exec('CREATE PROC MyProc AS SELECT ''Victory!''');
    end

まるで魔法のように機能します!

他のヒント

SET NOEXEC ON はコードの一部をオフにする良い方法です

IF NOT EXISTS (SELECT * FROM sys.assemblies WHERE name = 'SQL_CLR_Functions')
  SET NOEXEC ON
GO
CREATE FUNCTION dbo.CLR_CharList_Split(@list nvarchar(MAX), @delim nchar(1) = N',')
RETURNS TABLE (str nvarchar(4000)) AS EXTERNAL NAME SQL_CLR_Functions.[Granite.SQL.CLR.Functions].CLR_CharList_Split
GO
SET NOEXEC OFF

ここにあります:https://codereview.stackexchange.com/questions/10490/conditional-create-must-be-the-only-statement-in-the-batch

追伸別の方法は、parseonly {on |オフ }。

ただし、ストアド プロシージャ内の単一引用符に注意してください。単一引用符は 2 つ目の引用符を追加して「エスケープ」する必要があります。最初の回答でこれが完了しましたが、見逃した場合に備えて。若手選手の罠。

データベースのバージョン管理が最善の方法ですが...条件付きでストアド プロシージャを作成する理由。ビュー、ストアド プロシージャ、関数の場合は、条件付きで削除し、毎回再作成するだけです。条件付きで作成した場合、2 年前に一度削除したことを覚えていると確信していた別の開発者 (あなたや私なら決してそんなことはしません) によって問題やハッキングが行われたデータベースをクリーンアップすることはありません。緊急アップデート。

ドロップおよび作成の問題は、ドロップされるオブジェクトに以前に適用されていたセキュリティ許可が失われることです。

正直、私は通常 @Peter に同意します。私は条件付きで削除し、毎回無条件に再作成します。私はこれまで、バージョン管理の有無にかかわらず、データベース間のスキーマの違いを推測しようとして、何度も気づかされてきました。

そうは言っても、@Josh さん自身の提案は非常にクールです。確かに興味深いですね。:-)

これは古いスレッドですが、Jobo は間違っています。Create Procedure はバッチ内の最初のステートメントである必要があります。したがって、使用できません Exists 存在するかどうかをテストしてから、いずれかを使用します Create または Alter. 。残念。

私の解決策は、procが存在するかどうかを確認し、存在する場合は削除してからprocを作成することです(@robsoftと同じ答えですが、例があります...)

IF EXISTS(SELECT * FROM sysobjects WHERE Name = 'PROC_NAME' AND xtype='P') 
BEGIN
    DROP PROCEDURE PROC_NAME
END
GO
CREATE PROCEDURE PROC_NAME
    @value  int
AS
BEGIN
    UPDATE  SomeTable
    SET     SomeColumn = 1
    WHERE   Value = @value
END
GO

T-SQL の 'Exists' コマンドを使用して、ストアド プロシージャが存在するかどうかを確認します。存在する場合は「Alter」を使用し、そうでない場合は「Create」を使用します。

IF NOT EXISTS(SELECT * FROM sys.procedures WHERE name = 'pr_MyStoredProc')
BEGIN

     CREATE PROCEDURE pr_MyStoredProc AS .....
     SET NOCOUNT ON
END

ALTER PROC pr_MyStoredProc
AS
SELECT * FROM tb_MyTable
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top