SQL veritabanında bir işlevin var olup olmadığı nasıl kontrol edilir


138

Bir işlevi bir veritabanında var olup olmadığını bulmak gerekir, böylece onu bırakıp yeniden oluşturun. Temelde saklı yordamlar için kullandığım aşağıdaki kod gibi bir şey olmalıdır:

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

Yanıtlar:


206

DROP and CREATESeçeneği kullanarak komut dosyası yazarken SSMS'nin kullandığı budur

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 

Değişiklikleri dağıtmaya yönelik bu yaklaşım, nesnenin üzerindeki tüm izinleri yeniden oluşturmanız gerektiği anlamına gelir; böylece ALTERbunun yerine Var ise -ing'i düşünebilirsiniz .


17
Neden bir sys.functions sistemi katalog görünümü yok neden daha da merak ediyorsun .....
marc_s

61

Bilgi_Schema kullanma eğilimindedir:

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

işlevler ve Routine_Typesaklı yordamlar için değişiklik

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

2
Cool Böyle bir şey arıyordum ve hiç bulamadım. Belirli bir RDBMS bağlı olmadığından genel olarak info_schema kullanmanın daha iyi olduğuna inanıyorum. (btw platformlar arası uyumlu olma fikri şu yanıttan geldi: stackoverflow.com/a/14290099/420667 )
user420667

40

Neden sadece:

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

İkinci argümanı object_idisteğe bağlıdır, ancak doğru nesneyi tanımlamaya yardımcı olabilir. Bu tür argümanı için çok sayıda olası değer vardır , özellikle:

  • FN: Skaler fonksiyon
  • IF: Satır içi tablo değerli işlev
  • TF: Tablo değerli işlev
  • FS: Montaj (CLR) skaler fonksiyon
  • FT: Montaj (CLR) tablo değerli işlev

4
Teknik olarak bu, yalnızca o adda bir nesne olup olmadığını kontrol ettiğinden başarısız olabilir. Bir nesne olduğu ve bir işlev olduğu değil. EG CREATE TABLE YourFunctionName(X INT);O zaman kodun çalıştırılması başarısız olur.
Martin Smith

1
@MartinSmith: Sağlam hale getirmek kolaydır. Sadece kullanmak object_id('YourFunction', 'FN')veya yapar başka designator (ikinci argüman) tür nesnenin sen bahsettiğin şey temizleyin.
darlove

@darlove ikinci parametre olarak 'FN' kullanarak çalışmayabilir. Yeni öğrendim. 'FN' skaler fonksiyon anlamına gelir. Bu bağlantı size sqlhints.com/tag/how-to-check-if-function-exists iletebileceğiniz farklı parametre değerlerini gösterir . Varolan Tablo değeri işlevini denetlemek için 'FN' kullanmaya devam ediyorum ve çalışmıyor. 'TF' kullanmak zorundayım
user12345

9

Ben çeşitli SQL Server nesneleri bu şekilde varlığını kontrol etmek için çok ayrıntılı olmayan ve basit bir yaklaşım kullanabilirsiniz buldum:

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

Bu, SQL 2005 ve sonraki sürümlerde bulunan OBJECTPROPERTY işlevini temel alır. MSDN makalesine buradan ulaşabilirsiniz .

OBJECTPROPERTY işlevi aşağıdaki imzayı kullanır:

OBJECTPROPERTY ( id , property ) 

Aradığınız parametrenin türünü belirterek, özellik parametresine değişmez bir değer iletirsiniz. Sağlayabileceğiniz devasa bir değer listesi var.


Tam bir if / drop örneği içeriyorsa, bu cevabın basitliğini görmek daha kolay olacağını düşünüyorum.
Jonathan

6

Bu iş parçacığı eski olduğunu biliyorum ama sadece daha güvenlidir inananların için bu yanıta eklemek istedim Alterdaha Dropve Create. Aşağıda olacak varolduğundan veya eğer o değilse: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
Bunu beğendim, ama sanırım "ALTER FONKSİYONU" olmalı, değil mi?
Erik

SevdiğimALTER OR CREATE
AgentFire
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.