2012-12-13 14 views
19

Oracleは「作成または置換」ステートメントを実行します。 SQL Serverは、Enterprise Managerからスクリプトを作成する場合、代わりに代わりに「ドロップして作成する」ことを示唆しています。ドロップと作成は、データベース管理チームが行ったすべての権限付与を捨てるため、ストアドプロシージャの権限を与えている状況では望ましくありません。開発者と管理者の間の分離を助けるためには、実際には「作成または置き換え」が必要です。私は最近何をしてきたSQLストアドプロシージャがSQLサーバーに存在しない場合は作成

はこれです:

use [myDatabase] 
go 

create procedure myProcedure as 
begin 
    print 'placeholder' 
end 
go 

alter procedure myProcedure as 
begin 
    -- real sproc code here 
end 
go 

これは私が欲しいものを行います。プロシージャーが存在しない場合は作成し、正しいコードで変更してください。プロシージャーが存在する場合、作成は失敗し、alterは新しいコードでコードを更新します。

ストアドプロシージャが既に存在する場合、createによって誤解を招くエラーが発生するため、管理者には別の問題が発生します。もちろん、あなたが望む結果が出たときに赤いエラーテキストが表示されるべきではないという誤解を招くことがあります。

誰かが赤いテキストを抑制する方法はありますか?私が試したことは、「CREATE/ALTER PROCEDUREは何らかの形でクエリバッチの最初の文でなければなりません」というエラーにつながります。このよう

+0

可能な複製(http://stackoverflow.com/questions/1434160/what-do-you-do-in-sql -server-to-create-or-alter) – ruffin

+0

私は、あなたがあなたのprocの一部としてアクセス許可をスクリプト化するならば、DropとCreateに問題はないことを指摘します。あなたがprocに対して特別な権限を持っているなら、ソースコードリポジトリに格納されているスクリプトの一部でなければなりません。そして、あなたが変更を行うために行くとき、そこにpermissionareが既にあります。 – HLGEM

答えて

46

これは動作してそのままの権限を保持します:SQL Serverが作成するか、または交換するために同等のものを実装した場所

use [myDatabase] 
go 
if object_id('dbo.myProcedure', 'p') is null 
    exec ('create procedure myProcedure as select 1') 
go 
alter procedure myProcedure as 
SET NOCOUNT ON 
    -- real sproc code here. you don't really need BEGIN-END 
go 
+0

ハ。私はこのトリックを忘れていた。 – RBarryYoung

+0

私は私の初心者が好きです。 – quillbreaker

+0

これはユーザー定義関数でも機能します。これは関数がいくつか使用されていたために "alter"の必要性を発見した場所です。 OPに、これは好ましいオプション、IMHOでしょう。 – granadaCoder

9

IF NOT EXISTS (SELECT * FROM sys.objects 
       WHERE object_id = OBJECT_ID(N'[dbo].[myProcedure]') 
        AND type in (N'P', N'PC')) 
BEGIN 
    EXEC(' 
     create procedure myProcedure as 
     begin 
      print ''placeholder'' 
     end 
     ') 
END 

EXEC(' 
    alter procedure myProcedure as 
    begin 
     -- real sproc code here 
    end 
    ') 

NOTES:

  1. は、動的SQL文字列にあなたの引用符をダブルアップすることを忘れないでください。
  2. 私は可読性のためにインデントしましたが、実際のプロシージャリストに余分なインデントスペースも追加されます。それを覚えていない場合は、動的SQLテキストのインデントレベルを減らしてください。
+0

いつも、オンラインで投稿するときにBEGIN..ENDを追加しようとしています。ちょうど何回かの理由で、初心者が自分の足で自分自身を撃って、他の人のSQLに行を追加しようとしたときにBEGIN.ENDを追加するのを忘れてしまったのを見てきました。 – RBarryYoung

+0

本当に無関係です。新しい行の "GO"はそれを完全にスコープします。誰かが 'begin ... end'をやって、' END'の後で 'GO'の前にもっとステートメントを入れないのはどういうことでしょうか?しかしそれはちょうど意見であり、誰もが1つに権利がある! – RichardTheKiwi

+0

@RichardTheKiwi:それは珍しい間違いです。 (まあ、誤解GOはよくある間違いですが、通常は範囲外の変数とは違った形で現れます)通常、BEGIN..ENDの問題は、ブランチ内の複数のステートメントに必要であることを忘れてしまうことです/ブロック。いつBEGIN ..ENDはそこにあります。視覚的に "思い出させる"ように見えるので、新しい行をブロックの外に置くことはありません。 (少なくとも私は間違いを見たことはありません) – RBarryYoung

4

最後の日はここにあります。それらの同等物は「作成または変更」です。これはSQL Server 2016 SP1以降で使用できます。使用例:[?あなたが作成または変更するためにSQL Serverで何をしますか]の

use [myDatabase] 
go 

Create or Alter procedure myProcedure as 
begin 
    -- procedure code here 
end 
go 
関連する問題