Object_ID中不同类型的函数

Ken*_*nny 3 sql-server function objectid

在创建函数时,我倾向于在创建前加上存在性检查

IF Object_ID(N'myfunc', N'IF') IS NOT NULL 
DROP FUNCTION myfunc

GO
CREATE FUNCTION myfunc...
Run Code Online (Sandbox Code Playgroud)

有几种类型的object_id要检查函数:

FN = SQL scalar function
IF = SQL inline table-valued function
TF = SQL table-valued-function
FT = Assembly (CLR) table-valued function
Run Code Online (Sandbox Code Playgroud)

我有一些问题 :

  1. 'IF','TF''FT' 类型有什么区别?

  2. 它非常容易出错

    IF Object_ID(N'myFunc', 'IF') IS NOT NULL
    
    Run Code Online (Sandbox Code Playgroud)

    因为某个时候函数是标量,其他情况下它是表值等,所以我可能会错过正确的类型检查.

我看到人们推荐

IF EXISTS (SELECT * FROM sys.objects 
WHERE object_id = OBJECT_ID(N'myfunc') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
Run Code Online (Sandbox Code Playgroud)

检查所有类型的功能是否足够?你有什么建议?

Luk*_*zda 5

1)IF对多线TF对CLR TF

内联表值函数

宏,非常有效的行为可以像参数化视图一样对待

CREATE FUNCTION dbo.name(@param INT)
RETURNS TABLE
AS 
RETURN 
   SELECT ...
   FROM tab t
   WHERE t.Col = @param;
GO
Run Code Online (Sandbox Code Playgroud)

多语句表值函数

如果需要,您可以更灵活地执行许多中间步骤,但它会比IF慢.

CREATE FUNCTION dbo.name()
RETURNS @Result TABLE
(Col_name    INT         NOT NULL,
...
)
AS
BEGIN
    /* Many operations */

    INSERT @Result
    SELECT *
    FROM ...

    RETURN
END
GO
Run Code Online (Sandbox Code Playgroud)

CLR表值函数

来自MSDN

Transact-SQL表值函数将调用函数的结果实现为中间表.由于它们使用中间表,因此它们可以支持结果上的约束和唯一索引.返回大结果时,这些功能非常有用.

相反,CLR表值函数表示流式替代.不要求在单个表中实现整个结果集.托管函数返回的IEnumerable对象由调用表值函数的查询的执行计划直接调用,结果以增量方式使用.此流式传输模型可确保在第一行可用后立即消耗结果,而不是等待填充整个表.如果返回的行数非常多,它也是一个更好的选择,因为它们不必在整个内存中实现.例如,托管表值函数可用于解析文本文件并将每行作为一行返回.

2)检查功能是否存在:

检查ROUTINES目录:

为当前用户在当前数据库中可以访问的每个存储过程和函数返回一行.

IF EXISTS ( SELECT  1
            FROM INFORMATION_SCHEMA.ROUTINES
            WHERE Specific_schema = 'dbo'
              AND specific_name = 'Foo'
              AND Routine_Type = 'FUNCTION' ) 
Run Code Online (Sandbox Code Playgroud)