我可以控制SQL Server处理其执行计划的方式吗?

时间:2012-11-06 10:20:52

标签: sql-server sql-execution-plan

情况:

我经常(没有评论数据库,这是历史:) :)列中的值是分开的。

所以我们假设我们有一个params列,例如1,2,3,4,5

如果我需要基于值表,我将它们用dbo.fn_Split()函数拆分(可以在网上找到几个版本 - 但这里的范围超出范围)。所以我得到了我的虚拟桌子。

今天我遇到了一个情况,我有一个列,我有这个内容110&mode=tree

因为我需要ID只有我对自己说...像往常一样,拆分并获得第一个值:

SELECT TOP 1 [value] FROM dbo._fnSplit('110&mode=tree','&')

因为我需要将值作为int,所以我在它周围添加了一个CAST()。

CAST((SELECT TOP 1 [value] FROM dbo._fnSplit('110&mode=tree','&')) AS int)

现在执行后我得到了:

  

mode = tree无法转换为int类型

胡赫?我得到的第一个值是Id(我仔细检查了结果),但它仍然尝试转换第二个值。因此,似乎SQL Server在执行时处理它的方式不同。

问题:

通常可以控制执行计划如何处理这种行为吗?

旁注:

我现在解决了这个问题:

[...] WHERE id = CAST((CASE WHEN k.param LIKE '%&%' THEN LEFT(k.swindowparam,PATINDEX('%&%',k.param)-1) ELSE k.swindowparam END) AS int))

检查字符串是否包含&如果是这样的话,PATINDEX找到了长度为LEFT。

编辑:

这是拆分功能:

CREATE FUNCTION dbo.fn_Split(@text nvarchar(4000), @delimiter char(1) = ',')

RETURNS @Strings TABLE
(
position int IDENTITY PRIMARY KEY,
value nvarchar(4000)
)

AS
BEGIN

DECLARE @index int
SET @index = -1

SET @text = RTRIM(LTRIM(@text))

WHILE (LEN(@text) > 0)
BEGIN
SET @index = CHARINDEX(@delimiter , @text)
IF (@index = 0) AND (LEN(@text) > 0)
BEGIN
INSERT INTO @Strings VALUES (@text)
BREAK
END
IF (@index > 1)
BEGIN
INSERT INTO @Strings VALUES (LEFT(@text, @index - 1))
SET @text = RIGHT(@text, (LEN(@text) - @index))
END
ELSE
SET @text = RIGHT(@text, (LEN(@text) - @index))
END
RETURN
END

1 个答案:

答案 0 :(得分:1)

听起来你的split函数以未指定的顺序返回数据。为了解决这个问题,我会更改该函数,以便每次都以期望顺序返回结果。

根据函数的实现方式,您可以通过添加ORDER BY语句来纠正此行为。 SQL Server不保证默认情况下将以任何特定顺序返回集合。