0

我有一个查询,我必须从 varchar 列中提取一些数字字段。当我在 select 语句中进行一些替换和子字符串并将其转换为 bigint 时,一切正常,但是当我在 join 中使用相同的转换时,它会抛出错误“将数据类型 varchar 转换为 bigint 时出错”。这怎么可能?

select CAST(
        case when CHARINDEX('/',f.BML,1)>0 
            then substring(replace(replace(replace(replace(replace(replace(replace(replace(replace(f.BML,'A',''),'B',''),'C',''),'+',''),',',''),'S',''),'H',''),'P',''),'¸','') ,1,CHARINDEX('/',BML,1)-1)
        else replace(replace(replace(replace(replace(replace(replace(replace(replace(f.BML,'A',''),'B',''),'C',''),'+',''),',',''),'S',''),'H',''),'P',''),'¸','') 
        end as bigint)
from TableN n join TableO o  on
    n.Id=o.Id 
    join TableF f on
        f.OId=o.OId and
        substring(cast(n.RJ as varchar(10)),1,3)=substring(CAST(f.MT AS varchar(10)),1,3) and
    CAST(
        case when CHARINDEX('/',f.BML,1)>0 then substring(replace(replace(replace(replace(replace(replace(replace(replace(replace(f.BML,'A',''),'B',''),'C',''),'+',''),',',''),'S',''),'H',''),'P',''),'¸','') ,1,CHARINDEX('/',f.BML,1)-1)
        else replace(replace(replace(replace(replace(replace(replace(replace(replace(f.BML,'A',''),'B',''),'C',''),'+',''),',',''),'S',''),'H',''),'P',''),'¸','') 
        end as bigint) =n.mbr
order by n.Ident
4

1 回答 1

2

正如我在评论中指出的那样,无法保证评估条件的顺序。因此,如果您有:

    f.OId=o.OId and
    substring(cast(n.RJ as varchar(10)),1,3)=substring(CAST(f.MT AS varchar(10)),1,3) and
CAST(
    case when CHARINDEX('/',f.BML,1)>0 then substring(replace(replace(replace(replace(replace(replace(replace(replace(replace(f.BML,'A',''),'B',''),'C',''),'+',''),',',''),'S',''),'H',''),'P',''),'¸','') ,1,CHARINDEX('/',f.BML,1)-1)
    else replace(replace(replace(replace(replace(replace(replace(replace(replace(f.BML,'A',''),'B',''),'C',''),'+',''),',',''),'S',''),'H',''),'P',''),'¸','') 
    end as bigint) =n.mbr

并且要么 要么f.OId=o.OId应该substring(cast(n.RJ as varchar(10)),1,3)=substring(CAST(f.MT AS varchar(10)),1,3)消除具有BML不可转换为的值的行bigint,这不能保证不会尝试转换。


您可以尝试将应该消除错误BML值的过滤器移动到子查询或 CTE 中,但这仍然不能保证查询优化器不会将转换运算符下推到子查询中并且仍然会导致错误。

处理这个问题的唯一真正方法(不幸的是)是将查询分成两部分,消除第一个查询中不可转换的值,并将此查询的结果放在临时表/表变量中。然后使用这个临时表构建查询的后半部分。

于 2012-10-16T08:54:58.957 回答