我正在使用一个函数将逗号分隔的参数拆分为一个表来过滤存储过程中的结果。
如果它放在WHERE条件中,是否会为每一行调用以下函数(SplitStrList2Table)?
SQL:
SELECT * FROM result_after
WHERE result_after.DepartmentId IN
(SELECT item FROM [dbo].[SplitStrList2Table](@DepartmentIds))
使用临时表会有所作为吗?
功能SQL:
FUNCTION [dbo].[SplitStrList2Table]
(@List varchar(MAX))
RETURNS
@ParsedList table (item int)
AS
BEGIN
DECLARE @item varchar(800), @Pos int
SET @List = LTRIM(RTRIM(@List))+ ','
SET @Pos = CHARINDEX(',', @List, 1)
WHILE @Pos > 0
BEGIN
SET @item = LTRIM(RTRIM(LEFT(@List, @Pos - 1)))
IF @item <> ''
BEGIN
INSERT INTO @ParsedList (item)
VALUES (CAST(@item AS int))
END
SET @List = RIGHT(@List, LEN(@List) - @Pos)
SET @Pos = CHARINDEX(',', @List, 1)
END
RETURN
答案 0 :(得分:0)
如果它放在WHERE条件中,是否会为每一行调用以下函数(SplitStrList2Table)?
没有。这是一个多语种TVF。该计划将有一个序列运算符,它首先调用该函数并填充表变量,然后在计划的其余部分中使用它。
但这并不一定是理想的。即使它仅在您的拆分器代码不是非常优化时调用,另外您不会在表变量上声明可能有帮助的任何索引。此外,TVF返回的行数将有固定的估计值(除非支持interleaved execution的版本可以在表变量填充步骤之后重新编译计划。)