2016-10-31 25 views
7

Wszyscy wiemy, że typy tabel wartości definiowanych przez użytkownika SQL (UDT) nie mogą zostać usunięte, jeśli mają zależności/zależności. Dobrze.Typy tabel definiowane przez użytkownika SQL: Dlaczego możemy je usunąć, jeśli nie są używane jako parametr?

Ale dzisiaj upuściłem jedną, nawet jeśli mają na utrzymaniu. Tylko kryteria nie powinny być używane jako parametry obiektów DB, takich jak proc lub func.

CREATE TYPE FooUDT AS TABLE 
(
    ID int NOT NULL 
) 

Zależnie

CREATE PROCEDURE Bar 
as 
BEGIN 
    DECLARE @Identifier FooUDT 

    --Some operations on @Identifier 
END 
GO 

The FooUDT mogą zostać pominięte, ponieważ jest wykorzystywany wewnątrz Proc i nie jest parametrem. Ale po drodze nie można go zrzucić.

CREATE PROCEDURE Bar 
    @Identifier FooUDT readonly 
as 
BEGIN 
    --Some operations on @Identifier 
END 
GO 

Co bardziej interesujące jest to, że w obu przypadkach, jeśli możemy sprawdzić zależności, zarówno pokaże każdą inną nazwę. Jednak ten pierwszy przypadek można usunąć, ale nie ten drugi. Dlaczego to? Czy może czegoś brakuje?

+3

Prawdopodobnie wielka nieprawidłowość T-SQL, określana jako [rozpoznawanie nazw odroczonych] (https) : //technet.microsoft.com/library/ms190686). –

+1

@JeroenMostert: Z UDT jest inny. Jeśli brakuje UDT i składnia jest poprawna, proc nie jest nawet tworzony. –

+2

Wiedziałem, że nie powinienem zmienić "Odroczonej kompilacji" na "Odroczoną Rozpoznawanie Nazw". Ale idea jest taka sama: dla wszystkiego, co nie jest tabelą, składnia jest przetwarzana, a procedura nie jest tworzona, chyba że istnieją wszystkie obiekty. Ale nadal możesz swobodnie upuszczać te obiekty bez narzekania T-SQL, ponieważ kompilacja jest nadal odroczona. Odroczona kompilacja nie ma zastosowania do metadanych procedury składowanej, tylko do jej instrukcji, dlatego nie można usunąć UDT, jeśli jest używany jako parametr. –

Odpowiedz

4

Program SQL Server przechowuje treść procedury składowanej jako tekst, który znajduje się w treści procedury DECLARE @Identifier FooUDT.

Select text, * 
    from sysobjects A 
    JOIN syscomments B 
    On A.id = B.id   
    where xtype = 'P' 

Parametry są jednak przechowywane w metadanych. Można przeglądać je w następujący sposób ...

SELECT SCHEMA_NAME(SCHEMA_ID) AS[Schema], 
SO.name AS[ObjectName], 
SO.Type_Desc AS[ObjectType(UDF/SP)], 
P.parameter_id AS[ParameterID], 
P.name AS[ParameterName], 
TYPE_NAME(P.user_type_id) AS[ParameterDataType], 
P.max_length AS[ParameterMaxBytes], 
P.is_output AS[IsOutPutParameter] 
FROM sys.objects AS SO 
INNER JOIN sys.parameters AS P 
ON SO.OBJECT_ID = P.OBJECT_ID 
WHERE SO.OBJECT_ID IN(SELECT OBJECT_ID FROM sys.objects WHERE TYPE IN('P', 'FN')) 
ORDER BY[Schema], SO.name, P.parameter_id 

będę niech inni dostroić się tutaj, ale wierzę, że napotkasz sporo aktualizacji anomalie i problemy kaskadowe jeśli próbował sprawdzić ciał procedura zależności.

2
odpowiedź

Michaela Buller jest miejscem na

tylko parametry są sprawdzane na spadku, przechowywane PROC lub UDF ciała nie są; prosty przykład, dlaczego nie byłoby praktyczne, aby potwierdzić ciała, jest istnienie dynamicznego SQL przez sp_execute_sql

https://msdn.microsoft.com/en-us/library/ms188001.aspx

Innym powodem byłoby potrzeby rekompilacji wszystkie SPS/UDF na każdej zmianie schematu. Zamiast tego są one rekompilowane tylko na żądanie, szczególnie gdy są tworzone lub zmieniane.

Widać zależności, ponieważ zostały obliczone w czasie kompilacji; ale ponieważ zmiany mogły nastąpić, zależności nie są koniecznie aktualne, a DROP powinien działać dla kodu, który nie jest już ważny ...