SQL用户定义的表类型:如果不用作参数,为什么我们可以删除它们?

Nik*_*wal 7 sql t-sql sql-server user-defined-types

我们都知道,如果SQL用户定义的表值类型(UDT)具有依赖项/依赖项,则不能删除它们.对.

但是,即使他们有家属,今天我也放了一个.唯一的标准是它们不应该用作DB对象的参数,如proc或func.

CREATE TYPE FooUDT AS TABLE
(
  ID int NOT NULL
)
Run Code Online (Sandbox Code Playgroud)

依赖的

CREATE PROCEDURE Bar
as
BEGIN
    DECLARE @Identifier FooUDT

    --Some operations on @Identifier
END
GO
Run Code Online (Sandbox Code Playgroud)

FooUDT,因为它使用了proc中,而不是一个参数可以被丢弃.但是跟随方式它不能被丢弃.

CREATE PROCEDURE Bar 
    @Identifier FooUDT readonly
as
BEGIN
    --Some operations on @Identifier
END
GO
Run Code Online (Sandbox Code Playgroud)

更有趣的是,在这两种情况下,如果我们检查依赖关系,两者都会显示彼此的名称.然而,前一种情况可以被取消,但后者则不然.为什么这个?或者我错过了什么?

Mic*_*ler 4

SQL Server 将存储过程主体存储为DECLARE @Identifier FooUDT存储过程主体中的文本。

Select text, *
    from sysobjects A
    JOIN syscomments B
    On A.id = B.id        
    where xtype = 'P'
Run Code Online (Sandbox Code Playgroud)

然而参数存储在元数据中。您可以按如下方式查看它们...

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
Run Code Online (Sandbox Code Playgroud)

我会让其他人在这里插话,但我相信如果您尝试检查过程体的依赖关系,您会遇到相当多的更新异常和级联问题。