web-dev-qa-db-ja.com

ストアドプロシージャが既に存在するかどうかを検出する方法

ストアドプロシージャが存在する場合または存在しない場合に機能する展開スクリプトを作成する必要があります。つまり、存在する場合は変更する必要があり、存在しない場合は作成する必要があります。

どうすればSQLでこれを行うことができます。

SQL Server 2005を使用しています

124
GordyII

プロシージャを削除して作成すると、セキュリティ設定が失われます。これにより、DBAがいらいらしたり、アプリケーションが完全に壊れたりする可能性があります。

私がしているのは、まだ存在しない場合に簡単なストアドプロシージャを作成することです。その後、好みに応じてストアドプロシージャを変更できます。

IF object_id('YourSp') IS NULL
    EXEC ('create procedure dbo.YourSp as select 1')
GO
ALTER PROCEDURE dbo.YourSp
AS
...

このようにして、セキュリティ設定、コメント、およびその他のメタデータが展開を生き残ります。

156
Andomar

最もクリーンな方法は、その存在をテストし、存在する場合はドロップしてから、再作成することです。 IFステートメント内に「create proc」ステートメントを埋め込むことはできません。これはうまくいくはずです:

IF OBJECT_ID('MySproc', 'P') IS NOT NULL
DROP PROC MySproc
GO

CREATE PROC MySproc
AS
BEGIN
    ...
END
140
Aaron Alton

ストアドプロシージャのみを扱う場合、最も簡単な方法は、おそらくプロシージャを削除してから再作成することです。 SQL Serverのスクリプトの生成ウィザードを使用して、これを行うためのすべてのコードを生成できます。

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[YourSproc]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[YourSproc]

CREATE PROCEDURE YourSproc...
30
JasonS

SQL Server 2016 CTP3から、大きなIFラッパーの代わりに新しいDIEステートメントを使用できます。

構文:

ドロップ{PROC |手順} [存在する場合] {[schema_name。 ]プロシージャ} [、... n]

クエリ:

DROP PROCEDURE IF EXISTS usp_name

詳細 here

15
if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[xxx]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
BEGIN
CREATE PROCEDURE dbo.xxx

ここで、xxxはproc名です

10
Luke Schafer

すでに述べたことに加えて、別のアプローチを追加し、差分スクリプト展開戦略の使用を提唱したいと思います。 常に現在の状態を確認し、その状態に基づいて動作するステートフルスクリプトを作成する代わりに、既知のバージョンからアップグレードする一連のステートレススクリプトを介して展開します 。私はこの戦略を使用しましたが、展開スクリプトはすべて「IF」フリーであるため、大きな成果を上げています。

3
Remus Rusanu
IF OBJECT_ID('SPNAME') IS NULL
     -- Does Not Exists
ELSE
     -- Exists
2
Hemanshu Bhojak

次のようにクエリを記述できます。

IF OBJECT_ID('ProcedureName','P') IS NOT NULL
    DROP PROC ProcedureName
GO

CREATE PROCEDURE [dbo].[ProcedureName]
...your query here....

上記の構文をより具体的にするには:
OBJECT_IDは、データベース内のオブジェクトの一意のID番号です。これは、SQL Serverによって内部的に使用されます。 ProcedureNameに続いてオブジェクトタイプを渡すので、Pは、SQL ServerにProcedureNameというオブジェクトを見つける必要があることを伝えますタイプ手順、つまりP

このクエリはプロシージャを検索し、使用可能な場合は削除して新しいプロシージャを作成します。

OBJECT_IDおよびオブジェクトタイプの詳細については、次を参照してください。SYS.Objects

1
shary.sharath

私は、顧客が検証を拡張できるストアドプロシージャを持っています。存在する場合、変更したくない場合、作成したくない場合、私が見つけた最良の方法:

IF OBJECT_ID('ValidateRequestPost') IS NULL
BEGIN
    EXEC ('CREATE PROCEDURE ValidateRequestPost 
    @RequestNo VARCHAR(30),
    @ErrorStates VARCHAR(255) OUTPUT
AS
BEGIN
    SELECT @ErrorStates = @ErrorStates
END')
END
0
Adriaan Davel

以下のコードは、ストアドプロシージャが既に存在するかどうかを確認します。

存在する場合は変更され、存在しない場合は新しいストアドプロシージャが作成されます。

//syntax for Create and Alter Proc 
DECLARE @Create NVARCHAR(200) = 'Create PROCEDURE sp_cp_test'; 
DECLARE @Alter NVARCHAR(200) ='Alter PROCEDURE sp_cp_test'; 
//Actual Procedure 
DECLARE @Proc NVARCHAR(200)= ' AS BEGIN select ''sh'' END'; 
//Checking For Sp
IF EXISTS (SELECT * 
           FROM   sysobjects 
           WHERE  id = Object_id('[dbo].[sp_cp_test]') 
                  AND Objectproperty(id, 'IsProcedure') = 1 
                  AND xtype = 'p' 
                  AND NAME = 'sp_cp_test') 
  BEGIN 
      SET @Proc=@Alter + @Proc 

      EXEC (@proc) 
  END 
ELSE 
  BEGIN 
      SET @Proc=@Create + @Proc 

      EXEC (@proc) 
  END 

go 
0

より良いオプションは、Red-Gate SQL CompareやSQL Examinerなどのツールを使用して、違いを自動的に比較し、移行スクリプトを生成することです。

0
Kane