我有一个select语句,在几个字段中,我想检查另一个表中是否存在该记录的条目,如果存在,则输出1值,如果不存在,则提供另一个值。
最好的方法是什么?您何时使用存储过程以及何时使用UDF?
答案 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。