0

サブクエリとクロス適用する次のSQLクエリがあります。

SELECT 
    pm.[FileName] 
    ,REPLACE([Message], 'Upload End. Total Row:', '') cnt_char
    ,CAST(REPLACE([Message], 'Upload End. Total Row:', '') AS INT) AS row_count
FROM 
    dbo.ProductMaster pm
CROSS APPLY 
    (SELECT TOP 30 * 
     FROM dbo.ActivityLog lo 
     WHERE [Message] like 'Upload End%' 
       AND lo.[FileName] = pm.[FileName] 
     ORDER BY ActivityDate DESC) AS s

正常に動作しますが、select の 2 番目の式 ( ) を削除する,REPLACE([Message], 'Upload End. Total Row:', '') cnt_charと、次のエラーが発生します。

メッセージ 245、レベル 16、状態 1、行 1
varchar 値 'Upload Start' をデータ型 int に変換するときに変換に失敗しました。

サブクエリの where 句は、メッセージが「アップロード開始」であるすべての行を明確に除外する必要がありますが、なぜこのエラーが発生するのですか? CROSS APPLYを正しく使用していませんか?

4

2 に答える 2

1

SQL Server は、任意の順序でクエリを自由に実行できます。つまり、すべての行を選択し、後でフィルターを適用するだけです。同じ結果が保証される方法であれば、どのような方法で行ってもかまいません。

残念ながら、その保証にはリレーショナル ロジックのみが含まれ、演算子のキャストは含まれません。

1 つの方法は、ダブル チェックです。

case when Message like 'Upload End.%' then
    CAST(REPLACE([Message], 'Upload End. Total Row:', '') AS INT)
else null
end AS row_count
于 2013-06-18T20:37:31.070 に答える
1

SQL は記述言語であり、手続き型言語ではありません。のメソッドはcross apply、結果がどのように生成されるかを論理的に説明します。実行計画は指定しません。クエリ オプティマイザーは、正しい結果セットを生成する任意のクエリ プランを自由に選択できます。

2 つのクエリの実行計画を確認する必要があります。私の推測では、それらは根本的な点で異なっていると思います。型変換を処理する場合、変換前whereにフィルター処理する句に依存しないでください。代わりに、 を使用する必要があります。外部クエリは次のようになります。case

(case when [Message] like 'Upload End. Total Row:%'
      then CAST(REPLACE([Message], 'Upload End. Total Row:', '') AS INT)
      when isnumeric([Message]) = 1
      then cast([Message] as int)
end) as row_count;
于 2013-06-18T20:38:03.387 に答える