ファンシーな副選択を介してテーブルを別のテーブルで更新する方法があるかもしれませんが、最良のアプローチは、SQL API を使用してこれを行うプログラムを作成することだと思います (perl の場合は DBD::DB2 ドライバーを使用する DBI、 Java、または C ライブラリなど) を使用して SELECT を実行し、カーソルを使用して RESULTSET から各結果行をフェッチし、更新を行います。
PSEUDOCODE (あなたがよく知っている言語はわかりません):
dbHandle = sqllib->open_connection(database, user, password)
select_statement = dbHandle->prepare('SELECT id FROM idstoupdate')
update_statement = dbHandle->prepare('UPDATE clients SET col1=?, col2=? WHERE ID=?')
resultset = statement->execute(select_statement)
foreach (row in resultset) {
id = row.getColumn('id')
update_statement->execute('1','2',id)
}
dbHandle->disconnect();
エラーチェックを追加する必要があります。すべての更新を適用するか、まったく適用しない場合は、トランザクションを開始し、エラーがなければトランザクション全体をコミットする必要があります。DB2 Infocenterには、上記のすべてを行う方法に関する豊富な資料があります。
注:
のソース データがidstoupdate
ファイルの場合は、select ステートメントとidstoupdate
テーブルをロードする作業をスキップして、ファイルから読み取ってデータベースを更新するだけでかまいません。これは、テーブルの更新を処理する最も効率的な方法です。
単純に純粋な SQL を使用して別のテーブルからテーブルを更新する必要がある場合、最も一般的な例は次の形式です。
UPDATE table1 t1
SET (t1.field1, t1.field2) =
(
SELECT t2.field1,
t2.field2
FROM table2 t2
WHERE t1.joinfield = t2.joinfield
AND t2.criteriafield = 'qualifier'
)
WHERE EXISTS
(
SELECT 1
FROM table2
WHERE t1.joinfield = table2.joinfield
AND t2.criteriafield = 'qualifier'
)
これにより述語が削除されますIN
が、おそらくメモリやログスペースの効率はそれほど向上しません。また、選択、ループ、フェッチ、更新よりも単純ではないため、すべての基準が正しいことを確認する必要があります。あなたのケースは少し単純です-これはうまくいくと思いますが、それを試すにはdb2インスタンスが必要です:
UPDATE clients t1
SET t1.col1 = '1', col2 = 'y'
WHERE EXISTS
(
SELECT 1
FROM idstoupdate t2
WHERE t1.id = t2.id
)
編集:
あなたが与えたクエリが正当なクエリであるため、SQL squirrelから機能しなかったことに実際に驚いています。DB2 は SQL の最適化や最適なアクセス パスの決定に非常に優れているため、私が示した例と同じように機能することさえあります。
私の答えでは、テーブルを更新する最もメモリ効率の良い方法と、純粋な SQL を使用してあるテーブルの行を別のテーブルから更新する一般的なパターンを示そうとしていました (これは、1 つのテーブルに更新する行)。
さらに、最新のデータベース エンジンが簡単に処理できるとしても、20 を超える値を含む IN 述語には疑いがあります。
ただし、データベース エンジンがクエリを効率的に処理しているかどうかを調べたり、2 つの SQL クエリを比較したりする最善の方法は、SQL 説明コマンドを使用することです。