Sql server 对象ID中不同类型的函数

Sql server 对象ID中不同类型的函数,sql-server,function,objectid,Sql Server,Function,Objectid,在创建函数时,我倾向于在创建之前进行存在性检查 IF Object_ID(N'myfunc', N'IF') IS NOT NULL DROP FUNCTION myfunc GO CREATE FUNCTION myfunc... 有几种类型的功能需要检查: FN = SQL scalar function IF = SQL inline table-valued function TF = SQL table-valued-function FT = Assembly (CLR) ta

在创建函数时,我倾向于在创建之前进行存在性检查

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

GO
CREATE FUNCTION myfunc...
有几种类型的功能需要检查:

FN = SQL scalar function
IF = SQL inline table-valued function
TF = SQL table-valued-function
FT = Assembly (CLR) table-valued function
我有一些问题:

  • 'IF''TF''FT'类型之间有什么区别

  • 它使用起来非常容易出错

    IF Object_ID(N'myFunc', 'IF') IS NOT NULL
    
    因为有时函数是标量函数,其他情况下是表值函数等等,所以我可能会错过正确的类型检查

  • 我看到有人推荐

    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'))
    
    它是否足以检查所有类型的函数?您的建议是什么?

    1)如果vs多线TF vs CLR TF 内联表值函数

    就像宏一样,非常高效,可以像参数化视图一样处理

    CREATE FUNCTION dbo.name(@param INT)
    RETURNS TABLE
    AS 
    RETURN 
       SELECT ...
       FROM tab t
       WHERE t.Col = @param;
    GO
    
    多语句表值函数

    更灵活的是,如果需要,您可以执行许多中间步骤,但速度会慢于

    CREATE FUNCTION dbo.name()
    RETURNS @Result TABLE
    (Col_name    INT         NOT NULL,
    ...
    )
    AS
    BEGIN
        /* Many operations */
    
        INSERT @Result
        SELECT *
        FROM ...
    
        RETURN
    END
    GO
    
    CLR表值函数

    Transact-SQL表值函数具体化调用的结果 将函数转换为中间表。因为他们使用 中间表,它们可以支持约束和唯一索引 在结果上。这些功能在大型应用程序中非常有用 返回结果。

    相反,CLR表值函数表示流 备选方案。不要求完整的结果集 具体化在一个表中。返回的IEnumerable对象 托管函数由查询的执行计划直接调用 调用表值函数,结果在中使用 循序渐进的方式。这种流模型确保了结果可以 在第一行可用后立即使用,而不是 正在等待填充整个表。这也是一个更好的选择 如果返回的行数非常多,则可以选择此选项,因为 它们不必作为一个整体在记忆中具体化。例如 托管表值函数可用于解析文本文件和 将每行作为一行返回

    2) 检查函数是否存在: 检查目录:

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


    添加架构名称并删除对象类型。为什么需要检查对象是否是函数?仔细想想:

    if object_id(N'dbo.functionname') is not null
    drop function dbo.functionname
    go
    create function dbo.functionname ...
    
    。。。将删除函数(如果存在),然后创建它

    如果已经有一个名为“dbo.functionname”的对象,但它不是函数,则删除操作将失败。但无论您是否检查“dbo.functionname”是否为函数,这都是正确的

    换句话说,如果有一个名为
    dbo.functionname
    的表(或任何其他非函数对象),则

    if object_id(N'dbo.functionname', N'IF') -- equates to false
    drop function dbo.functionanme -- doesn't get run
    go
    create function dbo.functionname... -- generates error
    
    将在
    create
    函数上失败(因为不会删除表dbo.functionname)


    不能有两个具有相同schema.objectname的对象。因此,如果您只是检查对象id(N'schema.objectname'),您应该不会有问题。

    如果行为类似于宏且效率较高,则多行TF速度较慢,您应该尽可能使用if。信息架构表出了什么问题?(参见“例程”)@lad2025:当我创建函数“func”返回表返回(..)时,它是IF还是TF?@DavidBrabant:你能详细说明一下吗?
    if object_id(N'dbo.functionname', N'IF') -- equates to false
    drop function dbo.functionanme -- doesn't get run
    go
    create function dbo.functionname... -- generates error