0

varchar 列からいくつかの数値フィールドを抽出する必要があるクエリがあります。select ステートメントで置換と部分文字列を実行して bigint にキャストすると、すべて正常に動作しますが、この同じキャストを結合で使用すると、「データ型 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)の値を持つ行を削除する必要がありますが、変換が試行されないという保証はありません。BMLbigint


不適切な値を排除するフィルターをBMLサブクエリまたは CTE に移動しようとすることはできますが、それでもクエリ オプティマイザーが変換演算子をサブクエリに押し込んでエラーが発生しないという保証はありません。

これに対処する唯一の実際の方法は (残念ながら)、クエリを 2 つに分割し、最初のクエリで変換できない値を削除し、このクエリの結果を一時テーブル/テーブル変数に配置することです。次に、この一時テーブルを使用してクエリの後半を作成します。

于 2012-10-16T08:54:58.957 に答える