3

ロング トランザクションの一部である SQL ステートメントに問題があります。

UPDATE tab_1 LEFT JOIN tab_2 ON tab_1.id = tab_2.tab_1_id SET tab_1.something = 42 WHERE tab1.id = tab_2.tab_1_id;

すべてが単純で、tab_1 と tab_2 がデータベースに存在する限り正常に動作します。これは明らかです。;-)

問題は、トランザクションを 4 つの異なるサーバーでコミットする必要があり、tab_2 が「動的」テーブルであり、特定の db / db スキーマに存在する場合と存在しない場合があることです...

tab_2 が存在しない場合、データベースは例外をスローし、トランザクション全体はコミットされません。とにかく続行したいです(0行を更新するだけです)!

私はこのようなことを試しました:

UPDATE [all the same as above] WHERE tab1.id = tab_2.tab_1_id AND EXISTS (select 1 from pg_class where relname='tab_2');

...しかし、「例外チェック」は「where」条件の前に行われるため、まだ間違っています (結合で使用したいテーブルと同じです..)。

「純粋な」SQLでこれを行う方法はありますか? :)

次のようなもの: LEFT JOIN tab_2 IF tab_2 EXISTS (そうでない場合 - 何もしない、null を返すなど?)

pl/pgsql プロシージャでこれを行う方法があることは知っています。2 番目の可能性は、テーブルが存在しない場合は、ステートメントの前に作成することです。

しかし、これを 1 つのステートメントで行う簡単でエレガントな方法があるのではないでしょうか? :)

DBMS: PostgreSQL 9.2

4

1 に答える 1

2

UPDATEテーブルがなくても成功するステートメントはシンプルでエレガントだとは思いません。不思議で紛らわしいと思います。

そのテーブルが存在するかどうかをチェックする条件を含めて、存在する場合にのみ更新を実行するのはなぜですか?それははるかに明確になるでしょう。

tab_2別のオプションは、存在する場合はそれを指すビューを作成するか、そうでない場合は空のテーブルを指すビューを作成することです。これは、このようなクエリがたくさんあり、それらすべてを変更したくない場合に役立ちます。

更新:条件は次のようになります(関数またはBEGIN...ENDブロック内にある必要があります):

IF EXISTS (select 1 from pg_class where relname='tab_2') THEN 
   UPDATE...
END IF;

Postgresqlの詳細によっては、ステートメントに存在しないテーブルが見つかった場合UPDATE(私はPostgresqlユーザーではありません)、コンパイルに失敗する可能性があります。その場合、存在する場合はそれを指すビューを作成し、tab_2存在しない場合は空のテーブルを作成する必要があります。

于 2012-12-18T10:52:40.593 に答える