7.8.2。でデータ変更ステートメント
WITH
データ変更ステートメント7.8.2.WITH
あなたは、データ変更ステートメント(使用することができます
INSERT
、
UPDATE
、または
DELETE
で)
WITHを
。これはあなたのことができます
同じクエリに複数の異なる操作を実行します。例は次のとおりです。
あなたはとして、データ変更ステートメント(INSERT、UPDATE、またはDELETE)を使用することができます。クエリで異なるさまざまな操作を実行できるようにします。例えば:
(AS moved_rows WITH
製品FROM DELETE
どこ
"日付"> = '2010-10-01' AND
"日付" < '2010-11-01'
RETURNING *
)
INSERT INTO products_log
moved_rows SELECT * FROM。
このクエリでは、効果的にから行を移動させ
た製品
に
products_log
。
DELETE
での
WITHは
から指定した行を削除
製品を
そのによってその内容を返す、
RETURNING
句。その後、主要なクエリでは、その出力を読み込み、に挿入し
products_log
。
表中のこのクエリの製品の行がproducts_logテーブルに移動します。DELETEに沿って指定された製品を削除して句を返すことによって、返されたコンテンツを削除し、次にメインクエリの出力を読み込み、products_logテーブルに挿入されます。
上記の例の微細な点があることが
WITH
句が接続されている
INSERT
、ないサブ
SELECT
内の
INSERT
。データ修正文のみ許可されているので、これは必要である
に
WITH
トップレベルの声明に添付されている句。しかし、通常の
WITH
可視性ルールは
、参照することが可能であるので、適用
WITH
サブからの文の出力
SELECT
。
上記の一つの利点は、代わりにINSERT SELECT句のインサートに取り付けられた句と、例示的なものです。追加のデータ修正文が唯一の他の層、WITH句で許可されているので、これは、必要です。しかし、それは多くの場合、可視性のルールで使用されて、あなたはSELECT句からWITH文の出力を参照することができます。
データ修正文
WITHは
通常た
RETURNING
示すように、(セクション6.4を参照)句
上記の例では。それはの出力である
RETURNING
句、
ない
データ修正の対象テーブル
クエリの残りの部分によって参照することができ、一時テーブルを形成文。場合
のデータ修正文の
WITHが
欠けている
RETURNING
句を、それは何の一時テーブルを形成しないと
、クエリの残りの部分に言及することはできません。このような文は、それにもかかわらず実行されます。notparticularly-
有用な例は以下のとおりです。
図示のように、データ変更文は通常RETURNING句を持つWITH(参照6.4節を)。クエリで参照ではなく、ターゲット表のデータ定義文よりも、戻り値の句をREUTRNINGています。RETURNING句WITH内のデータ変更文が欠落している場合、それは一時テーブルを形成していない、とクエリで参照することはできません。それにもかかわらず、ステートメントが実行されます。ではない、特に有用な例:
T AS(WITH
FOO FROM DELETE
)
バーから削除します。
この例では、テーブルからすべての行を削除します
FOO
と
バー
。影響を受けた行の数が報告された
のみから削除行含まれるクライアントに
バーを
。
通常のfooとbarのテーブル上のすべての行を削除します。そして、行が影響を受けるクライアントにはバーテーブルからのみ参照されました。
データ修正文で再帰自己参照は許可されていません。場合によっては可能である
再帰の出力を参照することによってこの制限を回避するために
WITH
例えば:
データ変更ステートメントは、自分自身を再帰的に呼び出して使用することはできません。いくつかのケースでは、多くの場合、再帰との妥協点を呼び出すことにより、外でこの問題を解決します。例えば:
(AS RECURSIVE included_parts(sub_part、パート)WITH
sub_part、部品WHERE部分=「our_product」から一部を選択
UNION ALL
SELECT p.sub_part、p.part
included_partsのPR、部品Pから
WHERE p.part = pr.sub_part
)
部品FROM DELETE
WHERE部分IN(included_parts FROM SELECT部分)。
このクエリでは、製品のすべての直接および間接的なサブパーツを削除します。
このクエリでは、製品のすべての直接的または間接的に一部を削除します。
内のデータ修正文
WITHは
一度だけ実行され、常に完了するまで、独立
かどうかの主要なクエリでは、それらの出力の(実際にまたは任意の)すべて読み込みます。これは異なることに注意してください
のルールから
SELECT
で
WITH
前節で述べたように、の実行:
SELECTが
さ
までしか主なクエリは、その出力を要求して実施。
声明で、変更データは一度だけ実行され、常に(読み取りまたは実際に)すべての出力を読むかどうかをメインクエリで、完了するまで実行されるとは何の関係もありません。一つはSELECTを実装する前に、場合にのみ、メインクエリ必要の出力は、上述した:異なるルールSELECTであることに注意してください。
サブステートメント
WITHは
互いにメインクエリと並行して実行されます。
データ修正文を使用する場合したがって、
WITH
、指定された更新が順序
実際に起こるは予測不可能です。すべてのステートメントは同じで実行され
たスナップショット
(章を参照
、彼らがターゲット表上の相互の影響を「見る」ことができないので、13)。この緩和の効果
行更新の実際の順序の予測できない、ことを意味
RETURNING
データが唯一の方法であり、
異なるの間で変化し通信する
WITH
サブステートメントとメインクエリを。例
これはその中にあります
お互いの間で同時に実行WITHメインサブクエリステートメントを持ちます。このように、データ修正文WITH、実際の更新順序を指定すると、予期しないです。すべてのステートメントは、(参照、同じスナップショットを使用する第13章を)ので、彼らは、ターゲット表上で互いに影響を「見る」ことができません。この緩和する予測不可能性を更新された行、および唯一の方法は、メインクエリとの声明WITH異なるサブ間の変化をRETURNINGデータを転送することを意味し、実際の順序の影響。例えば:
T AS(WITH
UPDATE製品SET価格=価格* 1.05
RETURNING *
)
製品SELECT * FROM。
外側の
SELECTは、
のアクションの前に、元の価格を返します
UPDATE
でいる間、
SELECT文の外でUPDATEする前に元の価格を返し、そして:
T AS(WITH
UPDATE製品SET価格=価格* 1.05
RETURNING *
)
TからSELECT *;
外側の
SELECTは、
更新されたデータを返します。
SELECT文の外側には、更新の価格を返します。
サポートされていない単一のステートメントで二度同じ行を更新しようとしています。変更のみの一つが
行われますが、それは確実にどちらを予測するのは簡単(そして時にはことはできません)ではありません。また、これは
すでに同じ文で更新された行を削除するに適用されます。唯一の更新が行われます。
したがって、あなたは一般的に、単一のステートメントで二回、単一の行を変更しようとすることは避けてください。では
、特定の回避書き込み
WITH
メインによって変化し、同じ行に影響を及ぼす可能性がサブステートメント
ステートメントまたは兄弟サブステートメントを。そのような文の影響は予測できません。
これは、単一のステートメントで二度同じ行を更新しようとする試みをサポートしていません。変更のみの1は成功しますが、あなたは正確にどのような変化(時には不可能)を予測することはできません。これはまたに適用される
同じ文
の更新同じ行を削除するには、次の更新のみを行います。したがって、それは一般的に単一の文で二度同じ行を変更しようとする試みを避けるべきです。特に、サブステートメントとステートメントWITH書き込みを避けるためには、同じ行にメインのステートメントに影響します。そのような文の影響は予測不可能です。
現時点では、内のデータ修正文のターゲットとして使用する任意のテーブル
WITHは
条件付きあってはならない
ルール、また
ALSOの
ルールを、また
INSTEAD
複数のステートメントにその膨張しルール。
現在では、ターゲット表を修正するために声明で使用されるすべてのデータではなく、複数の文に拡張ルール、ルール、そのような条件を持っていなければなりません。