12

興味があるのは、以下の(簡略化された)例がこのように機能する理由です。

CREATE TABLE test (id SERIAL, val INT NOT NULL, PRIMARY KEY(id));
INSERT INTO test (val) VALUES (1);

WITH t AS ( UPDATE test SET val = 1 RETURNING id ) 
DELETE FROM test WHERE id IN ( SELECT id FROM t);

結果:
DELETE 0

質問:
DELETEが削除する行を見つけられなかったのはなぜですか?

PostgreSqlバージョン9.2.1
トランザクション分離=読み取りコミット

ありがとう!

4

1 に答える 1

14

私はそれがドキュメントのこの行と関係があると思います-

プライマリクエリとWITHクエリはすべて(概念的に)同時に実行されます。これは、WITHのデータ変更ステートメントの効果は、RETURNING出力を読み取る以外に、クエリの他の部分からは確認できないことを意味します。このような2つのデータ変更ステートメントが同じ行を変更しようとした場合、結果は指定されません。

WITHサブクエリではIDが変更されていないため、IDが使用可能になると思いますが、行の可視性で何かが起こっている可能性があります。「不特定」という用語はかなり曖昧です。これは、教祖の1人がそれにひびを入れることができるようにpostgresリストの質問かもしれません...

編集:もう少し情報を提供するために、私もに置き換えDELETEてみましたがSELECT *、これにより期待される行が返されました。私の即時の反応は、それらを返す行を見つけることができれば、それらを削除するためにそれらを見つけることができるはずであるということでした。しかし、もっと考えてみると、このテストは、データ変更ステートメントと非データ変更ステートメントの組み合わせが期待される結果を生成するのに対し、2つのデータ変更ステートメントが予期しない結果を生成するという点で引用をサポートします。

于 2012-12-10T18:36:39.613 に答える