SQLデータベースに関数が存在するかどうかを確認する方法


138

関数がデータベースに存在するかどうかを確認して、関数を削除して再作成できるようにする必要があります。基本的には、ストアドプロシージャに使用する次のコードのようになります。

IF EXISTS (
     SELECT  *
     FROM    dbo.sysobjects
     WHERE   id = OBJECT_ID(N'[dbo].[SP_TEST]')
             AND OBJECTPROPERTY(id, N'IsProcedure') = 1 )

回答:


206

これは、DROP and CREATEオプションを使用してスクリプトを作成するときにSSMSが使用するものです

IF EXISTS (SELECT *
           FROM   sys.objects
           WHERE  object_id = OBJECT_ID(N'[dbo].[foo]')
                  AND type IN ( N'FN', N'IF', N'TF', N'FS', N'FT' ))
  DROP FUNCTION [dbo].[foo]

GO 

変更をデプロイするこのアプローチでは、オブジェクトのすべての権限を再作成する必要があるため、ALTER代わりに存在する場合は-ingを検討できます。


17
なぜsys.functionsシステムカタログビューがないの、もっと不思議に思います...
marc_s

61

私はInformation_Schemaを使用する傾向があります:

IF EXISTS ( SELECT  1
            FROM    Information_schema.Routines
            WHERE   Specific_schema = 'dbo'
                    AND specific_name = 'Foo'
                    AND Routine_Type = 'FUNCTION' ) 

関数の場合、およびRoutine_Typeストアドプロシージャの変更

IF EXISTS ( SELECT  1
            FROM    Information_schema.Routines
            WHERE   Specific_schema = 'dbo'
                    AND specific_name = 'Foo'
                    AND Routine_Type = 'PROCEDURE' ) 

2
クールこのようなものを探していましたが、見つかりませんでした。特定のRDBMSに関連付けられていないため、一般にinformation_schemaを使用する方が良いと思います。(クロスプラットフォーム互換であるという概念は、この回答から来ました:stackoverflow.com/a/14290099/420667
user420667

40

なぜか:

IF object_id('YourFunctionName', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION [dbo].[YourFunctionName]
END
GO

の2番目の引数object_idはオプションですが、正しいオブジェクトを識別するのに役立ちます。このtype引数には、特に次のような多数の可能な値があります。

  • FN:スカラー関数
  • IF:インラインテーブル値関数
  • TF:テーブル値関数
  • FS:アセンブリ(CLR)スカラー関数
  • FT:アセンブリ(CLR)テーブル値関数

4
技術的には、その名前のオブジェクトがあるかどうかをチェックするだけなので、失敗する可能性があります。オブジェクトはなく、関数でもありません。EGもしその場合CREATE TABLE YourFunctionName(X INT);、コードの実行は失敗します。
Martin Smith

1
@MartinSmith:堅牢にするのは簡単です。ただ、使用object_id('YourFunction', 'FN')またはそれはあなたが参照しているオブジェクトの種類のものを明確にし、他の指示(第二引数)。
darlove 2017

2番目のパラメータとして「FN」を使用する@darloveは機能しない場合があります。私はちょうど学んだ。「FN」はスカラー関数を意味します。このリンクは、sqlhints.com/tag/how-to-check-if-function-existsに渡すことができるさまざまなパラメーター値を示しています。'FN'を使用して既存のテーブル値関数をチェックし続けますが、機能しません。「TF」を使用する必要があります
user12345

9

このように、さまざまなSQL Serverオブジェクトの存在を確認するために、非常に冗長ではない簡単なアプローチを使用できることがわかりました。

IF OBJECTPROPERTY (object_id('schemaname.scalarfuncname'), 'IsScalarFunction') = 1
IF OBJECTPROPERTY (object_id('schemaname.tablefuncname'), 'IsTableFunction') = 1
IF OBJECTPROPERTY (object_id('schemaname.procname'), 'IsProcedure') = 1

これは、SQL 2005+で使用可能なOBJECTPROPERTY関数に基づいています。MSDNの記事はここにあります

OBJECTPROPERTY関数は次のシグネチャを使用します。

OBJECTPROPERTY ( id , property ) 

プロパティパラメータにリテラル値を渡し、探しているオブジェクトのタイプを指定します。提供できる値の膨大なリストがあります。


完全なif / dropの例が含まれている場合、この回答の単純さを確認する方が簡単だと思います。
ジョナサン

6

私は、このスレッドが古いです知っているが、私はちょうどそれがより安全だと考えている人のために、この答えを追加したいAlter以上DropCreate。下記の意志が存在する場合、またはしない場合は:AlterFunctionCreate

  IF NOT EXISTS (SELECT *
               FROM   sys.objects
               WHERE  object_id = OBJECT_ID(N'[dbo].[foo]')
                      AND type IN ( N'FN', N'IF', N'TF', N'FS', N'FT' ))
       EXEC('CREATE FUNCTION [dbo].[foo]() RETURNS INT AS BEGIN RETURN 0 END')
  GO
  ALTER FUNCTION [dbo].[foo]
  AS
  ...

2
私はこれが好きですが、それは「ALTER FUNCTION」であるべきだと思います、いいえ?
エリック

気に入ったALTER OR CREATE
AgentFire
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.