2016-10-31 26 views
7

Chúng ta đều biết rằng các kiểu bảng giá trị bảng do người dùng định nghĩa SQL (UDT) không thể bị loại bỏ nếu chúng có phụ thuộc/phụ thuộc. Đúng.Các loại bảng do người dùng định nghĩa SQL: Tại sao chúng ta có thể thả chúng nếu không được sử dụng làm tham số?

Nhưng, hôm nay tôi đã giảm ngay cả khi họ có người phụ thuộc. Chỉ tiêu chí là chúng không nên được sử dụng làm tham số của các đối tượng DB như proc hoặc func.

CREATE TYPE FooUDT AS TABLE 
(
    ID int NOT NULL 
) 

phụ thuộc

CREATE PROCEDURE Bar 
as 
BEGIN 
    DECLARE @Identifier FooUDT 

    --Some operations on @Identifier 
END 
GO 

Các FooUDT có thể được giảm vì nó được sử dụng bên trong một proc và không phải là một tham số. Nhưng theo cách nó không thể bị vứt bỏ.

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

Điều thú vị hơn là trong cả hai trường hợp, nếu chúng tôi kiểm tra phụ thuộc, cả hai sẽ hiển thị tên khác. Tuy nhiên, các trường hợp trước đây có thể được giảm xuống nhưng không phải là sau này. Tại sao lại như vậy? Hay tôi đang thiếu một cái gì đó?

+3

Khả năng xảy ra lỗi lớn của T-SQL được gọi là [độ phân giải tên trì hoãn] (https : //technet.microsoft.com/library/ms190686). –

+1

@JeroenMostert: Với UDT khác biệt của nó. Nếu thiếu UDT và cú pháp đúng, thì proc thậm chí không được tạo ra. –

+2

Tôi biết tôi không nên thay đổi "biên dịch trì hoãn" thành "độ phân giải tên trì hoãn". Nhưng ý tưởng là như nhau: đối với bất cứ thứ gì không phải là bảng, cú pháp được phân tích cú pháp và quy trình không được tạo trừ khi tất cả các đối tượng tồn tại. Nhưng sau đó bạn vẫn được tự do thả các đối tượng đó mà không có T-SQL phàn nàn, bởi vì việc biên dịch vẫn được trì hoãn. Việc biên dịch trì hoãn không áp dụng cho siêu dữ liệu của thủ tục đã lưu trữ, chỉ với các phát biểu của nó, đó là lý do tại sao bạn không thể bỏ UDT nếu nó được sử dụng như một tham số. –

Trả lời

4

Máy chủ SQL lưu trữ cơ thể Thủ tục được lưu trữ dưới dạng văn bản mà DECLARE @Identifier FooUDT của bạn nằm trong phần thân của quy trình.

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

Thông số được lưu trữ trong siêu dữ liệu. Bạn có thể xem chúng như sau ...

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 

tôi sẽ cho người khác kêu vang ở đây, nhưng tôi tin rằng bạn sẽ chạy vào một vài cập nhật bất thường và các vấn đề thác nếu bạn đã cố gắng để kiểm tra cơ quan tiến hành đối với phụ thuộc.

2

Câu trả lời của Michael Buller được đặt tại số

Chỉ các thông số được xác thực trên thả, procs lưu trữ hoặc UDF không phải; một ví dụ đơn giản về việc tại sao nó sẽ không được thực hiện để xác nhận cơ quan, là sự tồn tại của SQL động qua sp_execute_sql

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

Một lý do khác sẽ là sự cần thiết phải biên dịch lại tất cả SPs/UDFs trên tất cả các thay đổi giản đồ. Thay vào đó, chúng chỉ được biên dịch lại theo yêu cầu, đặc biệt khi được tạo hoặc thay đổi.

Bạn thấy các phụ thuộc vì chúng được tính toán tại thời gian biên dịch; nhưng vì các thay đổi có thể bị mờ, các phụ thuộc không được cập nhật thường xuyên và DROP sẽ hoạt động đối với mã không còn hợp lệ nữa ...

Các vấn đề liên quan