在SQL中键入比较

时间:2010-07-22 18:57:31

标签: sql tsql implicit-conversion

作为SQL Query的一部分,我有以下代码:

INSERT INTO [Database]  
 SELECT DISTINCT @ssId 
   FROM [Document_Map] 
  WHERE (LabelId IN (SELECT Tokens 
                       FROM StringSplitter(@sortValue, '|', 1))

只要@SortValue是一个整数,(LabelId也是一个int)或由分隔符分隔的整数(例如,SortValue 420 | 421 |与420和421)。但是,我正在添加涉及@sortValue的非整数值的功能。例如:420|ABC|421| 与420,ABC和421进行比较。

不用担心,我想。我只想修改该查询的最后一行!

(LabelId IN (SELECT Tokens FROM StringSplitter(@sortValue, '|', 1)) OR 
StringId IN (SELECT Tokens FROM StringSplitter(@sortValue, '|', 1)))

不幸的是,每当我在@sortValue中输入字符时,我都会收到错误消息。它从未进入or的远端。

经过多次扫描后,我终于确定SQL正在从StringSplitter函数中转换字符串结果以与LabelId进行比较。当字符串结果保证只包含数字字符时没问题,但SQL拒绝将(非常可理解)非数字字符串强制转换为int,从而抛出错误。

在保持所需功能的同时解决此错误的最简单方法是什么?由于数据库交互,我不确定更改LabelId的类型是否可行。

3 个答案:

答案 0 :(得分:4)

扩展DCP所说的内容,试试这段代码:

(Convert(varchar(32),LabelId) IN (SELECT Tokens FROM StringSplitter(@sortValue, '|', 1)) OR 
StringId IN (SELECT Tokens FROM StringSplitter(@sortValue, '|', 1)))

请注意性能问题,在WHERE子句中进行转换会导致问题......

答案 1 :(得分:4)

我有建议但也有问题......

根本原因是Datatype precedence规则。

我没有得到的是为什么将数字列与字符串数据进行比较?为什么要发送非数字数据进行比较?

如果将int LabelID“24”转换为字符串与“024”字符串进行比较,则会失败。字符串“024”在转换为int时变为“24”并且匹配。你想要和期望什么行为?

我可以理解使用ISNUMERIC修复损坏的架构或整理数据,但您似乎故意发送字符串。

无论如何,你的修复是

  • 更改列类型以匹配您发送的内容
  • CAST the column
  • 在字符串拆分(例如“StringSplitterToInt”)或客户端
  • 中过滤掉比较中的字符串

我建议使用数字1来反映您的模型和实际数据,或建议使用数字3来修复您的代码......

答案 2 :(得分:2)

对于您的功能问题,请尝试ISNUMERIC:

; WITH data (Foo) AS (
             SELECT '1'
   UNION ALL SELECT 'abc'
)
SELECT
   *
FROM data
WHERE ISNUMERIC(Foo) = 1;

此外,如果您的Split函数使用任何其他表(如公共数字表),请将拆分部分移出SELECT语句并将结果存储在临时表中。在语句的WHERE部分中使用模式绑定调用表值函数可以(并且经常会)导致对表的每一行调用函数。