MS Sql 2k和2k5之间的不一致,列作为函数参数

时间:2008-08-25 17:38:50

标签: sql-server

我无法在SQL Server 2k中使用以下内容,但它适用于2k5:

--works in 2k5, not in 2k

create view foo as    
SELECT  usertable.legacyCSVVarcharCol as testvar     
FROM  usertable   
WHERE rsrcID in
    (  select val     
       from
       dbo.fnSplitStringToInt(usertable.legacyCSVVarcharCol, default)
    )

--error message:    
Msg 170, Level 15, State 1, Procedure foo, Line 4    
Line 25: Incorrect syntax near '.'.

因此,legacyCSVVarcharCol是一个包含以逗号分隔的INT列表的列。我意识到这是一个巨大的WTF,但这是遗留代码,现在没有什么可以对模式做的。将“testvar”作为函数的参数传递在2k中也不起作用。实际上,它会导致稍微不同(甚至更奇怪的错误):

Msg 155, Level 15, State 1, Line 8

'testvar' is not a recognized OPTIMIZER LOCK HINTS option.

将硬编码字符串作为fnSplitStringToInt的参数传递到2k和2k5。

有谁知道为什么这在2k不起作用?这可能是查询规划器中的已知错误吗?有关如何使其工作的任何建议?我再次意识到真正的答案是“不要在你的数据库中存储CSV列表!”,但是,这是我无法控制的。

一些示例数据,如果它有帮助:

INSERT INTO usertable (legacyCSVVarcharCol) values ('1,2,3');
INSERT INTO usertable (legacyCSVVarcharCol) values ('11,13,42');

请注意,表中的数据似乎并不重要,因为这是一个语法错误,即使usertable完全为空也会发生。

编辑:意识到最初的例子可能不清楚,这里有两个例子,其中一个有效,另一个没有,这应该突出正在发生的问题:

--fails in sql2000, works in 2005

SELECT t1.* 
FROM usertable t1
WHERE 1 in 
    (Select val 
     from 
     fnSplitStringToInt(t1.legacyCSVVarcharCol, ',')
    )

--works everywhere:

SELECT t1.*   
FROM usertable t1
WHERE 1 in 
    ( Select val 
      from 
      fnSplitStringToInt('1,4,543,56578', ',')
    )

请注意,唯一的区别是fnSplitStringToInt的第一个参数是2k中失败的情况下的一个列,以及两个成功的情况下的文字字符串。

2 个答案:

答案 0 :(得分:1)

SQL Server 2000不支持将列值传递给表值用户定义的函数,只能使用常量,因此以下(更简单的版本)也会失败:

SELECT *, (SELECT TOP 1 val FROM dbo.fnSplitStringToInt(usertable.legacyCSVVarcharCol, ','))
FROM usertable

它可以在SQL Server 2005上运行,正如您所发现的那样。

答案 1 :(得分:0)

我不认为函数在SS2K中的函数中可以有默认值。

在SS2K中运行此SQL时会发生什么?

select val     
from dbo.fnSplitStringToInt('1,2,3', default)