ストアドプロシージャが存在する場合または存在しない場合に機能する展開スクリプトを作成する必要があります。つまり、存在する場合は変更する必要があり、存在しない場合は作成する必要があります。
どうすればSQLでこれを行うことができます。
SQL Server 2005を使用しています
プロシージャを削除して作成すると、セキュリティ設定が失われます。これにより、DBAがいらいらしたり、アプリケーションが完全に壊れたりする可能性があります。
私がしているのは、まだ存在しない場合に簡単なストアドプロシージャを作成することです。その後、好みに応じてストアドプロシージャを変更できます。
IF object_id('YourSp') IS NULL
EXEC ('create procedure dbo.YourSp as select 1')
GO
ALTER PROCEDURE dbo.YourSp
AS
...
このようにして、セキュリティ設定、コメント、およびその他のメタデータが展開を生き残ります。
最もクリーンな方法は、その存在をテストし、存在する場合はドロップしてから、再作成することです。 IFステートメント内に「create proc」ステートメントを埋め込むことはできません。これはうまくいくはずです:
IF OBJECT_ID('MySproc', 'P') IS NOT NULL
DROP PROC MySproc
GO
CREATE PROC MySproc
AS
BEGIN
...
END
ストアドプロシージャのみを扱う場合、最も簡単な方法は、おそらくプロシージャを削除してから再作成することです。 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...
SQL Server 2016 CTP3
から、大きなIF
ラッパーの代わりに新しいDIEステートメントを使用できます。
構文:
ドロップ{PROC |手順} [存在する場合] {[schema_name。 ]プロシージャ} [、... n]
クエリ:
DROP PROCEDURE IF EXISTS usp_name
詳細 here
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名です
すでに述べたことに加えて、別のアプローチを追加し、差分スクリプト展開戦略の使用を提唱したいと思います。 常に現在の状態を確認し、その状態に基づいて動作するステートフルスクリプトを作成する代わりに、既知のバージョンからアップグレードする一連のステートレススクリプトを介して展開します 。私はこの戦略を使用しましたが、展開スクリプトはすべて「IF」フリーであるため、大きな成果を上げています。
IF OBJECT_ID('SPNAME') IS NULL
-- Does Not Exists
ELSE
-- Exists
次のようにクエリを記述できます。
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
私は、顧客が検証を拡張できるストアドプロシージャを持っています。存在する場合、変更したくない場合、作成したくない場合、私が見つけた最良の方法:
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
以下のコードは、ストアドプロシージャが既に存在するかどうかを確認します。
存在する場合は変更され、存在しない場合は新しいストアドプロシージャが作成されます。
//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
より良いオプションは、Red-Gate SQL CompareやSQL Examinerなどのツールを使用して、違いを自動的に比較し、移行スクリプトを生成することです。