4

これを短く理解しやすくするために、テーブルとフィールドの名前を変更したことに注意してください。

要約すると、次のようなクエリがあります。

update destTable 
set destField = ( select top 1 isnull(s.sourceField, '') from sourceTable s 
where <various matches between the destTable table and the s table>
);

(「update destTable set destField ... from destTable d, sourceTable s ...」という構文は知っていますが、「上位 1」を入れる方法がわかりません。)

これから、SQLServer 2012 Express の結果を取得します。

Msg 515, Level 16, State 2, Line 1
Cannot insert the value NULL into column 'destField', table 'destTable'; column does not allow nulls. UPDATE fails.
The statement has been terminated.

両方のテーブルで、すべてのフィールドが非 null およびデフォルト ('') として定義されています。

sourceTable には「where」句に複数の一致がある可能性があるため、「トップ 1」は重要です。

sourceTable のすべての行を照会したところ、sourceField のすべての値が null ではないことがわかりました。それでも私は結果を得る。

クエリの性質は、おそらく 1000 の destTable レコードのうち、sourceTable との一致で 300 行しか一致しないということです。他の 700 個の destTable レコードには一致がありません。

SQLServer が何をしているのか理解できません。このクエリは、最後に MySQL で実行したときに問題なく動作しました。

前もってありがとう、ジェローム。

4

1 に答える 1

7

問題は、クエリが行を返さないことです。. . したがって、NULL 値が生成されます。isNULL()サブクエリの外側に移動します。

update destTable 
set destField =  isnull((select top 1 s.sourceField
                         from sourceTable s 
                         where <various matches between the destTable table and the s table>
                        ), '');

ちなみに、coalesce()それが標準なので、通常はこの状況で主張します。ただし、Aaron Bertrandがここで説明しているように、2 つの動作は異なります。特に、最初の引数は 2 回評価されるように見えます。これは、サブクエリの場合は非常にコストがかかります。 Isnull()、明らかに、この問題はありません。

于 2013-07-22T13:15:15.860 に答える