我们都知道,如果SQL用户定义的表值类型(UDT)具有依赖项/依赖项,则不能删除它们。右。
但是,即使他们有家属,今天我也放了一个。唯一的标准是它们不应该用作DB对象的参数,如proc或func。
CREATE TYPE FooUDT AS TABLE
(
ID int NOT NULL
)
依赖
CREATE PROCEDURE Bar
as
BEGIN
DECLARE @Identifier FooUDT
--Some operations on @Identifier
END
GO
可以删除FooUDT
,因为它在proc中使用并且不是参数。但是跟随方式它不能被删除。
CREATE PROCEDURE Bar
@Identifier FooUDT readonly
as
BEGIN
--Some operations on @Identifier
END
GO
更有趣的是,在这两种情况下,如果我们检查依赖关系,两者都会显示彼此的名称。然而,前一种情况可以被取消,但后者则不然。为什么会这样呢?或者我错过了什么?
答案 0 :(得分:4)
SQL Server将存储过程主体存储为DECLARE @Identifier FooUDT
在过程正文中的文本。
Select text, *
from sysobjects A
JOIN syscomments B
On A.id = B.id
where xtype = 'P'
然而,参数存储在元数据中。您可以按照以下方式查看它们......
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
我会让其他人在这里说话,但我相信如果你试图检查程序主体的依赖关系,你会遇到很多更新异常和级联问题。
答案 1 :(得分:2)
迈克尔·布勒的回答是
只有在drop,存储过程或UDF主体上验证参数;一个简单的例子,说明为什么验证实体是不切实际的,是通过sp_execute_sql存在动态SQL
https://msdn.microsoft.com/en-us/library/ms188001.aspx
另一个原因是需要在每次架构更改时重新编译所有SP / UDF。相反,它们只是按需重新编译,特别是在创建或更改时。
您会看到依赖项,因为它们是在编译时计算的;但由于可能已经发生了变化,因此依赖关系不是最新的,DROP应该适用于不再有效的代码......