2013-08-26 17 views
5

Mam historycznie stosowane następujące jako część zapisanego skryptu wdrażania procedury:Jaki jest preferowany sposób określić, czy procedura przechowywana istnieje

IF NOT EXISTS (SELECT * FROM sys.objects O 
    WHERE O.[object_id] = OBJECT_ID(N'[dbo].[SPROC_NAME]') 
    AND OBJECTPROPERTY(O.[object_id],N'IsProcedure') = 1) 

    EXEC('CREATE PROCEDURE [dbo].[SPROC_NAME] AS') 
GO 

ALTER PROCEDURE [dbo].[SPROC_NAME] 
AS 
BEGIN ... 

nie wiedziałem o przeciążeniu do OBJECT_ID który trwa wpisz identyfikator obiektu dla odnośnika, na przykład:

OBJECT_ID(N'[dbo].[SPROC_NAME]', N'P') 

wydaje się, że przy użyciu tego przeciążenia uczyniłoby odnośnika OBJECTPROPERTY niepotrzebne.

Chciałbym wiedzieć, czy istnieje jakakolwiek wada polegająca na przeciążeniu i porzuceniu wyszukiwania OBJECT_ID i porzuceniu wyszukiwania OBJECTPROPERTY.

+1

Obiekty SQL mają tę samą unikalną przestrzeń nazw. 'OBJECT_ID' zwraca identyfikator obiektu o tej nazwie, jeśli istnieje. "OBJECTPROPERTY" potwierdza, że ​​obiekt jest faktycznie procedurą zapisaną, ponieważ może istnieć tabela lub widok o nazwie "[SPROC_NAME]" (a jeśli tak, to nie będzie można utworzyć sproca z tą nazwą). – RBarryYoung

+0

Jeśli zostanie podany drugi parametr, funkcja "OBJECT_ID" zwróci wartość inną niż null, jeśli obiekt tego typu istnieje. (Pamiętaj, aby określić schemat, nie wiem co się stanie, jeśli jest to tabela w jednym schemacie, a procedura w innym ...) –

Odpowiedz

3

Wolę tę formę, i przestali używając OBJECT* funkcje metadanych jak najwięcej jak to możliwe, ponieważ they can block even at loose isolation levels:

IF NOT EXISTS 
(
    SELECT 1 FROM sys.procedures AS p 
    INNER JOIN sys.schemas AS s 
    ON p.[schema_id] = s.[schema_id] 
    WHERE p.name = N'Procedure_Name' AND s.name = N'dbo' 
) 
BEGIN 
    EXEC sp_executesql N'CREATE PROCEDURE dbo.Procedure_Name AS'; 
END 
+0

+1. Mam tendencję do upuszczania, jeśli już istnieją, a następnie odtwarzają, aby upewnić się, że zawsze otrzymuję najnowszą wersję ... –

+0

@Mitch the CREATE stub pozwala prawdziwemu ciału być zawsze ALTEREM, nawet jeśli procedura nie istnieją jeszcze, więc nie wszystkie muszą być dynamiczne SQL. –

+0

Dobra uwaga. ... –

0

moja 0,02 $ -

Użyj object_id metoda z 2 parametru. Ułatwia czytanie kodu.

+0

'sys.objects' nie jest ani tabelą systemową, ani widokiem zgodności wstecznej. Jest to widok katalogu i myślę, że to dość subiektywne, czy 'OBJECT_ID()' jest łatwiejszy do odczytania, nieważne, że wiele takich funkcji metadanych nie stosuje się do semantyki poziomu izolacji (co oznacza, że ​​mogą one blokować nawet jeśli ustawiłeś read_uncommitted lub snapshot). –

1

Twój stan może być nieco krótszy:

IF OBJECT_DEFINITION(OBJECT_ID('dbo.Procedure_Name', 'P')) IS NULL 
    BEGIN 
     EXEC sys.sp_executesql 'CREATE PROCEDURE dbo.Procedure_Name AS' 
    END 

inny sposób:

IF OBJECT_ID('dbo.Procedure_Name', 'P') IS NULL 
    BEGIN 
     EXEC sys.sp_executesql 'CREATE PROCEDURE dbo.Procedure_Name AS' 
    END 
1

Mój preferowany sposób to:

if object_id('x') is not null 
    begin 
    drop procedure x 
    end 
    go 
    create procedure x ... 
    ... 
Powiązane problemy