使用列作为函数参数的MS Sql 2k和2k5之间的不相容
时间:2020-03-05 18:42:55 来源:igfitidea点击:
我无法使以下内容在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列表!"但是,a,这超出了我的控制范围。
一些样本数据,如果有帮助的话:
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中失败的情况下是一列,而在两个方面都成功的情况下是文字字符串。
解决方案
回答
我不认为函数可以在SS2K中的函数中具有默认值。
在SS2K中运行此SQL会发生什么?
select val from dbo.fnSplitStringToInt('1,2,3', default)
回答
SQL Server 2000不支持将列值传递给表值用户定义函数,我们只能使用常量,因此以下内容(简单版本)也将失败:
SELECT *, (SELECT TOP 1 val FROM dbo.fnSplitStringToInt(usertable.legacyCSVVarcharCol, ',')) FROM usertable
如我们所知,它将在SQL Server 2005上运行。