クライアントが「データベース管理」機能を実行するたびに実行する必要があるSQLスクリプトがあります。このスクリプトには、クライアントデータベースでストアドプロシージャを作成することが含まれています。これらのクライアントの中には、スクリプトの実行時にストアード・プロシージャーをすでに持っているものもあれば、そうでないものもあります。欠けているストアドプロシージャをクライアントデータベースに追加する必要がありますが、T-SQL構文をどれだけ曲げようとしても構いません。
CREATE/ALTER PROCEDURE 'は、クエリバッチの最初のステートメントでなければなりません
私は作品を作成する前にそれを落とすことを読みましたが、私はそのようにするのは好きではありません。
IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'MyProc')
DROP PROCEDURE MyProc
GO
CREATE PROCEDURE MyProc
...
ストアドプロシージャの存在の確認を追加し、存在しない場合は作成し、存在する場合は変更する方法を教えてください。
クエリを実行できる場所ならどこでも手続き型コードを実行できます。
AS
の後にすべてをコピーするだけです。
BEGIN
DECLARE @myvar INT
SELECT *
FROM mytable
WHERE @myvar ...
END
このコードは、ストアドプロシージャとまったく同じ動作をしますが、データベース側には格納されません。
これはPL/SQL
で無名手続きと呼ばれるものとよく似ています。
更新:
あなたの質問のタイトルは少しわかりにくいです。
プロシージャが存在しない場合にのみプロシージャを作成する必要がある場合は、コードは問題ありません。
CreateスクリプトでSSMS
が出力する内容は次のとおりです。
IF EXISTS ( SELECT *
FROM sys.objects
WHERE object_id = OBJECT_ID(N'myproc')
AND type IN ( N'P', N'PC' ) )
DROP …
CREATE …
更新:
スキーマをインクルードするときの方法の例
IF EXISTS ( SELECT *
FROM sysobjects
WHERE id = object_id(N'[dbo].[MyProc]')
and OBJECTPROPERTY(id, N'IsProcedure') = 1 )
BEGIN
DROP PROCEDURE [dbo].[MyProc]
END
上記の例では、dboがスキーマです。
更新:
SQL Server 2016以降では、あなただけができる
CREATE OR ALTER PROCEDURE dbo.MyProc
これはすでに回答済みとマークされていますが、以前は次のようにしていました。
IF NOT EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND OBJECT_ID = OBJECT_ID('dbo.MyProc'))
exec('CREATE PROCEDURE [dbo].[MyProc] AS BEGIN SET NOCOUNT ON; END')
GO
ALTER PROCEDURE [dbo].[MyProc]
AS
....
手順を落とさないようにするためだけに。
削除する前にデータベースオブジェクトの存在をチェックする最も簡単な方法を探しているのであれば、これが1つの方法です(上の例とまったく同じようにSPROCを使用しますが、テーブル、インデックスなどに変更できます)。
IF (OBJECT_ID('MyProcedure') IS NOT NULL)
DROP PROCEDURE MyProcedure
GO
これは迅速でエレガントですが、それを考慮に入れていないため、すべてのオブジェクト・タイプにわたって固有のオブジェクト名があることを確認する必要があります。
私はこれが役立つことを願っています!
「プロシージャが存在する場合は変更し、存在しない場合のみ削除する」ことをお勧めしますが、常にプロシージャを削除してから再作成するほうが簡単だと思います。プロシージャがすでに存在する場合にのみドロップする方法は次のとおりです。
IF OBJECT_ID('MyProcedure', 'P') IS NOT NULL
DROP PROCEDURE MyProcedure
GO
2番目のパラメータは、 OBJECT_ID
に、ストアドプロシージャであるobject_type = 'P'
、 を持つオブジェクトのみを検索するように指示します。
AF =集約関数(CLR)
C = CHECK制約
D = DEFAULT(制約またはスタンドアロン)
F =外部キー制約
FN = SQLスカラー関数
FS =アセンブリ(CLR)スカラー関数
FT =アセンブリ(CLR)テーブル値関数
IF = SQLインライン表値関数
IT =内部テーブル
P = SQLストアドプロシージャ
PC =アセンブリ(CLR)ストアドプロシージャ
PG =プランガイド
PK = PRIMARY KEY制約
R =ルール(旧スタイル、スタンドアロン)
RF =複製フィルター手順
S =システムベーステーブル
SN =同義語
SO =シーケンスオブジェクト
TF = SQLテーブル値関数
次の方法でオプションの全リストを入手できます。
SELECT name
FROM master..spt_values
WHERE type = 'O9T'
SQL Server 2016以降、新しいDROP PROCEDURE IF EXISTS
を使用できます。DROP { PROC | PROCEDURE } [ IF EXISTS ] { [ schema_name. ] procedure } [ ,...n ]
これは非常に古い投稿ですが、これはトップの検索結果に表示されるため、SQL Server 2016 SP1を使用している人のための最新の更新を追加します -
create or alter procedure procTest
as
begin
print (1)
end;
go
これは、ストアドプロシージャが存在しない場合は作成しますが、存在する場合は変更します。
私は同じエラーがありました。私はこのスレッドがすでにかなり死んでいることを知っていますが、「匿名手続き」以外に別のオプションを設定したいと思います。
私はこのように解決しました:
ストアドプロシージャが存在するかどうかを確認します。
IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='my_procedure') BEGIN
print 'exists' -- or watever you want
END ELSE BEGIN
print 'doesn''texists' -- or watever you want
END
しかし"CREATE/ALTER PROCEDURE' must be the first statement in a query batch"
はまだそこにあります。私はこのように解決しました:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE -- view procedure function or anything you want ...
私はこのコードで終わります:
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID('my_procedure'))
BEGIN
DROP PROCEDURE my_procedure
END
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].my_procedure ...
これがこのように使う方法とその背後にあるいくつかの推論です。ストアドプロシージャを編集するのはそれほどきれいではありませんが、長所と短所があります。
更新:この呼び出し全体をTRANSACTIONで囲むこともできます。すべてのコミットまたはすべてのロールバックが可能な単一のトランザクションに多数のストアドプロシージャを含める。トランザクションをラップするもう1つの利点は、READ UNCOMMITTEDトランザクション分離レベルを使用していない限り、ストアドプロシージャが他のSQL接続にも常に存在することです。
1)プロセスの決定として変更を避けるため。私たちのプロセスは、存在する場合は常に存在するIFを作成することです。新しいPROCが望ましいPROCであると想定するのと同じパターンを実行した場合、IF EXISTS ALTER ELSE CREATEがあるため、変更を提供することは少し難しくなります。
2)動的SQLの外側のトランザクションでプロシージャー更新のシーケンスをラップできないように、CREATE/ALTERを最初の呼び出しとしてバッチに入れる必要があります。基本的に、DBバックアップを復元せずにプロシージャー更新のスタック全体を実行したり、それらすべてをロールバックしたりしたい場合は、これをすべて1回のバッチで実行する方法です。
IF NOT EXISTS (select ss.name as SchemaName, sp.name as StoredProc
from sys.procedures sp
join sys.schemas ss on sp.schema_id = ss.schema_id
where ss.name = 'dbo' and sp.name = 'MyStoredProc')
BEGIN
DECLARE @sql NVARCHAR(MAX)
-- Not so aesthetically pleasing part. The actual proc definition is stored
-- in our variable and then executed.
SELECT @sql = 'CREATE PROCEDURE [dbo].[MyStoredProc]
(
@MyParam int
)
AS
SELECT @MyParam'
EXEC sp_executesql @sql
END
SQL Server 2008以降では、 "INFORMATION_SCHEMA.ROUTINES
"を使用できます。
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_NAME = 'MySP'
AND ROUTINE_TYPE = 'PROCEDURE')
DROP IF EXISTSはSQL Server 2016の新機能です。
DROP PROCEDURE IF EXISTS dbo.[procname]
投票やコメントに必要な評判は明らかにないのですが、EXECを使用したGeoffの回答(sp_executesqlのほうが良いかもしれません)が間違いなく有効な方法であると言いたいです。ストアドプロシージャを削除してから再作成すると、最終的にはジョブが完了しますが、ストアドプロシージャがまったく存在しない場合があります。繰り返し実行します。バックグラウンドスレッドがストアドプロシージャを使用しようとしていると同時にバックグラウンドスレッドがIF EXISTS DROP ... CREATEを実行していたため、私は自分のアプリケーションにさまざまな問題を抱えていました。
これが私が使うスクリプトです。それによって、私は不必要に保存されたprocを落として作り直すことを避けます。
IF NOT EXISTS (
SELECT *
FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[uspMyProcedure]')
)
BEGIN
EXEC sp_executesql N'CREATE PROCEDURE [dbo].[uspMyProcedure] AS select 1'
END
GO
ALTER PROCEDURE [dbo].[uspMyProcedure]
@variable1 INTEGER
AS
BEGIN
-- Stored procedure logic
END
** T-Sqlでストアドプロシージャを削除して再作成する最も簡単な方法は**
Use DatabaseName
go
If Object_Id('schema.storedprocname') is not null
begin
drop procedure schema.storedprocname
end
go
create procedure schema.storedprocname
as
begin
end
なぜあなたはのような簡単な方法で行かないでください
IF EXISTS(SELECT * FROM sys.procedures WHERE NAME LIKE 'uspBlackListGetAll')
BEGIN
DROP PROCEDURE uspBlackListGetAll
END
GO
CREATE Procedure uspBlackListGetAll
..........
私は疑問に思う!なぜ私は全体のクエリを書かないのですか
GO
create procedure [dbo].[spAddNewClass] @ClassName varchar(20),@ClassFee int
as
begin
insert into tblClass values (@ClassName,@ClassFee)
end
GO
create procedure [dbo].[spAddNewSection] @SectionName varchar(20),@ClassID int
as
begin
insert into tblSection values(@SectionName,@ClassID)
end
Go
create procedure test
as
begin
select * from tblstudent
end
私はすでに最初の2つの手続きが既に存在することを知っています。クライアント!
@ Geoff からの回答に加えて、ストアドプロシージャ、ビュー、関数、およびトリガ用のSQLファイルを生成する簡単なツールを作成しました。 。
MyDbUtils @ CodePlex を参照してください。