2015-06-24 29 views
0

在SQL Server 2008 R2上编写Sql命令时出现问题。
事实是,我有数字和nvarchar数据存储在同一列(IMP_VALUE)。 当我尝试执行此命令SQL Server - SQL由于多数据类型而选择问题子句

Select count(*) 
from IMPORTBM 
    inner join ATTRIBUTE on ATT_ATTRIBUTE_ID = IMP_ATTRIBUTE_ID 
where IMP_LOCATION_ID = 1 
    AND IMP_SERIAL_ID = 58 
    AND IMP_VERSION_ID = 1 
    AND 
     ((ATT_ATTRIBUTE = 'GBHT' AND IMP_VALUE = 'NA') 
     OR (ATT_ATTRIBUTE = 'GBLOPK' AND IMP_VALUE = 'NA') 
     OR (ATT_ATTRIBUTE = 'BRGLWLNG' AND IMP_VALUE = 0.603) 
     OR (ATT_ATTRIBUTE = 'MSZ' AND IMP_VALUE IN ('LMV-321','LMV-322')) 
     OR (ATT_ATTRIBUTE = 'GBACCK' AND IMP_VALUE IN ('NA','WARNING_NoValueFound')) 
     OR (ATT_ATTRIBUTE = 'GBTHLWLOC' AND IMP_VALUE IN ('NA','WARNING_NoValueFound'))) 

,它失败,出现错误:

消息8114,级别16,状态5,行1
错误的数据类型为varchar转换为数字。

当然,我为了使这项工作

CAST(IMP_VALUE as numeric) = 0.603 

改变这一点,但事实并非如此。

当我只执行命令的第一部分,一切工作正常

Select count(*) 
from IMPORTBM 
    inner join ATTRIBUTE on ATT_ATTRIBUTE_ID = IMP_ATTRIBUTE_ID 
where IMP_LOCATION_ID = 1 
    AND IMP_SERIAL_ID = 58 
    AND IMP_VERSION_ID = 1 
    AND 
     ((ATT_ATTRIBUTE = 'GBHT' AND IMP_VALUE = 'NA') 
     OR (ATT_ATTRIBUTE = 'GBLOPK' AND IMP_VALUE = 'NA') 
     OR (ATT_ATTRIBUTE = 'BRGLWLNG' AND CAST(IMP_VALUE as numeric) = 0.603)) 

但是,当我加入where最后3行:

 OR (ATT_ATTRIBUTE = 'MSZ' AND IMP_VALUE IN ('LMV-321','LMV-322')) 
     OR (ATT_ATTRIBUTE = 'GBACCK' AND IMP_VALUE IN ('NA','WARNING_NoValueFound')) 
     OR (ATT_ATTRIBUTE = 'GBTHLWLOC' AND IMP_VALUE IN ('NA','WARNING_NoValueFound'))) 

,它无法与同错误代码比以前!
有人知道为什么它只能在没有in行的情况下工作吗?
另外,你有什么可以使这项工作?
非常感谢!

+1

如果你的领域是VARCHAR,那么你为什么不这样做'AND IMP_VALUE =“0.603''?这可以避免查询在与'0.603'比较之前尝试将其中的'NA'行转换为NUMERIC ... – MatBailie

+0

因为我可以使用多个运算符(例如>,< > =,<=,in,不在,之间),而这个where子句是动态的,它根据我的用户需要创建数字和varchar值。 (我不确定是否清楚,我的英语很差...) – KrasshX

+0

然后你依靠短路;当ATT_ATTRIBUTE ='BRGLWLNG''条件失败时,优化器知道不应用'CAST(IMP_VALUE AS NUMERIC)'。由于WHERE子句的复杂性导致短路失败,或者即使在ATT_ATTRIBUTE ='BRGLWLNG'时,IMP_VALUE中的值也不是数值。 – MatBailie

回答

0

尝试运行此查询,看看双方的值实际数值...

SELECT MIN(IMP_VALUE), MAX(IMP_VALUE) FROM ATTRIBUTE WHERE ATT_ATTRIBUTE = 'BRGLWLNG'; 

我敢肯定你在里面有价值观,不能转化为NUMERIC

您的OR需要将其过滤掉,或者您需要修正这些值,以便它们的格式正确的字符串表示形式为NUMERIC


另外请注意,你只是用NUMERIC,和SQL Server的帮助页说,这只是一样NUMERIC(18,0); 18位数字,小数点后无数字。尝试更合适的数据类型(以下是蛮力选项) ...

OR ( ATT_ATTRIBUTE      = 'BRGLWLNG' 
    AND ISNUMERIC(IMP_VALUE)    = 1 
    AND CAST(IMP_VALUE AS NUMERIC(38,19)) = 0.603 
) 
+0

第一个查询返回:1.400 \t 1.400 – KrasshX

+0

你问我做的第二件事情完美无缺!!谢谢!!但是为什么当我尝试使用float数据类型时,这工作不正常? – KrasshX

+0

@KrasshX - 那是不是工作?错误的结果,错误信息? – MatBailie