存储过程与UDF

时间:2010-04-14 00:42:05

标签: sql-server tsql sql-server-2008

我有一个select语句,在几个字段中,我想检查另一个表中是否存在该记录的条目,如果存在,则输出1值,如果不存在,则提供另一个值。

最好的方法是什么?您何时使用存储过程以及何时使用UDF?

3 个答案:

答案 0 :(得分:4)

我会使用Left Join

Select Coalesce(OtherTable.Field, 'Default Value') As Value
From Table
    Left Join OtherTable On Table.OtherTableId = OtherTable.Id
Where Table.Id = @Id

答案 1 :(得分:1)

通常我会尽可能使用视图来封装低级逻辑和符合。如果参数化视图(即内联表值函数)允许您强制执行某些参数,我会使用它。如果需要执行多语句操作,那么我将使用存储过程。

视图和内联表值函数的好处是优化器可以更容易地操作它们(视图可以组合在构建执行计划中),视图和ITVF可以像表一样使用并连接到其他表,与重复内联代码相比,实际上很少或没有开销的视图或ITVF。

例如,ChaosPandion's answer中的代码可以封装在带有参数的ITVF中(这是确保始终提供某些参数的好方法 - 在视图中无法确保过滤条件正在进行要在外部SELECT)或视图中提供(并且需要在视图外部提供参数)。两种情况下的执行计划实际上都是等效的,因为优化器可以很好地处理这样的情况。

如果不先将数据放入临时表,则无法连接存储过程结果集。

CREATE VIEW TableWithDefault
AS
Select Table.Id, Coalesce(OtherTable.Field, 'Default Value') As Value
From Table
    Left Join OtherTable On Table.OtherTableId = OtherTable.Id

-- Usage: SELECT * FROM TableWithDefault WHERE Id = @Id

CREATE FUNCTION TableWithDefault(@Id int)
RETURNS TABLE
RETURN (
    Select Coalesce(OtherTable.Field, 'Default Value') As Value
    From Table
        Left Join OtherTable On Table.OtherTableId = OtherTable.Id
    Where Table.Id = @Id
)

-- Usage: SELECT * FROM TableWithDefault(@Id)

现在这样做的好处是可以从各种存储过程,视图(OUTER APPLY,CROSS APPLY)等调用这个逻辑,逻辑总是在一个地方。

答案 2 :(得分:0)

关于UDF的好处是你可以在其他查​​询中使用它们。例如,您可以说:

SELECT my_UDF( t.id ) FROM my_table t

您还可以像表格一样使用UDF:

SELECT * FROM my_udf() t

因此,如果您认为您的查询包含可能在您的应用程序/数据库中的多个查询中使用的一些通用逻辑,您可能需要考虑使用UDF。但是有一些限制。例如,UDF无法调用非确定性内置函数,例如GETDATE。因此,您需要使用存储过程来处理这些函数。有关详细信息,请参阅:difference-between-user-defined-function-and-stored-procedure