39.4. ÐÑавила Ð´Ð»Ñ INSERT, UPDATE и DELETE #
ÐÑавила, опÑеделÑемÑе Ð´Ð»Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´ INSERT, UPDATE и DELETE, знаÑиÑелÑно оÑлиÑаÑÑÑÑ Ð¾Ñ Ð¿Ñавил пÑедÑÑавлений, опиÑаннÑÑ
в пÑедÑдÑÑиÑ
ÑазделаÑ
. Ðо-пеÑвÑÑ
, команда CREATE RULE позволÑÐµÑ ÑоздаваÑÑ Ð¿Ñавила Ñо ÑледÑÑÑими оÑобенноÑÑÑми:
Ðни могÑÑ Ð½Ðµ опÑеделÑÑÑ Ð´ÐµÐ¹ÑÑвиÑ.
Ðни могÑÑ Ð¾Ð¿ÑеделÑÑÑ Ð½ÐµÑколÑко дейÑÑвий.
Ðни могÑÑ Ð´ÐµÐ¹ÑÑвоваÑÑ Ð² Ñежиме
INSTEADилиALSO(по ÑмолÑаниÑ).СÑановÑÑÑÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ñми пÑевдооÑноÑениÑ
NEWиOLD.Ðни могÑÑ Ð¸Ð¼ÐµÑÑ ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¿ÑименениÑ.
Ðо-вÑоÑÑÑ , они не модиÑиÑиÑÑÑÑ Ñамо иÑÑ Ð¾Ð´Ð½Ð¾Ðµ деÑево запÑоÑа. ÐмеÑÑо ÑÑого они ÑоздаÑÑ Ð½ÐµÑколÑко новÑÑ Ð´ÐµÑевÑев запÑоÑов и могÑÑ Ð·Ð°Ð¼ÐµÐ½Ð¸ÑÑ Ð¸ÑÑ Ð¾Ð´Ð½Ð¾Ðµ.
Ðнимание
Ðо многиÑ
ÑлÑÑаÑÑ
Ð´Ð»Ñ Ð·Ð°Ð´Ð°Ñ, вÑполнимÑÑ
Ñ Ð¸ÑполÑзованием пÑавил Ð´Ð»Ñ INSERT/UPDATE/DELETE, лÑÑÑе пÑименÑÑÑ ÑÑиггеÑÑ. ÐÑоÑмлÑÑÑÑÑ ÑÑиггеÑÑ ÑÑÑÑ Ñложнее, но понÑÑÑ Ð¸Ñ
ÑмÑÑл гоÑаздо пÑоÑе. Ð ÑÐ¾Ð¼Ñ Ð¶Ðµ Ñ Ð¿Ñавилами могÑÑ Ð±ÑÑÑ Ð¿Ð¾Ð»ÑÑÐµÐ½Ñ Ð½ÐµÐ¾Ð¶Ð¸Ð´Ð°Ð½Ð½Ñе ÑезÑлÑÑаÑÑ, когда иÑÑ
однÑй запÑÐ¾Ñ ÑодеÑÐ¶Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÑивÑе ÑÑнкÑии: в пÑоÑеÑÑе иÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ñавил ÑÑи ÑÑнкÑии могÑÑ Ð²ÑзÑваÑÑÑÑ Ð±Ð¾Ð»ÑÑее ÑиÑло Ñаз, Ñем ожидаеÑÑÑ.
ÐÑоме Ñого, в некоÑоÑÑÑ
ÑлÑÑаÑÑ
ÑÑи ÑÐ¸Ð¿Ñ Ð¿Ñавил вообÑе нелÑÐ·Ñ Ð¿ÑименÑÑÑ; а именно, Ñ Ð¿ÑедложениÑми WITH в иÑÑ
одном запÑоÑе и Ñ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð½Ñми подзапÑоÑами SELECT Ñ Ð¼Ð½Ð¾Ð¶ÐµÑÑвеннÑм пÑиÑваиванием в ÑпиÑке SET запÑоÑов UPDATE. ÐÑо обÑÑÑнÑеÑÑÑ Ñем, ÑÑо копиÑование ÑÑиÑ
конÑÑÑÑкÑий в запÑÐ¾Ñ Ð¿Ñавила пÑивело Ð±Ñ Ðº многокÑаÑÐ½Ð¾Ð¼Ñ Ð²ÑÑиÑÐ»ÐµÐ½Ð¸Ñ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð½Ð¾Ð³Ð¾ запÑоÑа, ÑÑо поÑло Ð±Ñ Ð² ÑазÑез Ñ Ð²ÑÑаженнÑми намеÑениÑми авÑоÑа запÑоÑа.
39.4.1. Ðак ÑабоÑаÑÑ Ð¿Ñавила Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ #
ÐапомниÑе ÑинÑакÑиÑ:
CREATE [ OR REPLACE ] RULEимÑAS ONÑобÑÑиеTOÑаблиÑа[ WHEREÑÑловие] DO [ ALSO | INSTEAD ] { NOTHING |команда| (команда;команда... ) }
РдалÑнейÑем, под пÑавилами Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´ÑазÑмеваÑÑÑÑ Ð¿Ñавила, опÑеделÑемÑе Ð´Ð»Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´ INSERT, UPDATE или DELETE.
ÐÑавила Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿ÑименÑÑÑÑÑ ÑиÑÑемой пÑавил, когда ÑезÑлÑÑиÑÑÑÑее оÑноÑение и Ñип ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð² деÑеве запÑоÑа ÑÐ¾Ð²Ð¿Ð°Ð´Ð°ÐµÑ Ñ Ð¾Ð±ÑекÑом и ÑобÑÑием, заданнÑм в команде CREATE RULE. ÐÐ»Ñ Ñакого пÑавила ÑиÑÑема пÑавил ÑоздаÑÑ ÑпиÑок деÑевÑев запÑоÑов. ÐзнаÑалÑно ÑÑÐ¾Ñ ÑпиÑок пÑÑÑ. С пÑавилом Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑвÑзано Ð½Ð¾Ð»Ñ (клÑÑевое Ñлово NOTHING), одно или неÑколÑко дейÑÑвий. ÐÑоÑÑоÑÑ Ñади Ð¼Ñ ÑаÑÑмоÑÑим пÑавило Ñ Ð¾Ð´Ð½Ð¸Ð¼ дейÑÑвием. ÐÑавило Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð¼ÐµÑÑ, а Ð¼Ð¾Ð¶ÐµÑ Ð½Ðµ имеÑÑ ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¿ÑименениÑ, и дейÑÑвÑÐµÑ Ð² Ñежиме INSTEAD или ALSO (по ÑмолÑаниÑ).
ЧÑо Ñакое ÑÑловие пÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ñавила? ÐÑо ÑÑловие, коÑоÑое говоÑиÑ, когда нÑжно, а когда не нÑжно пÑименÑÑÑ Ð´ÐµÐ¹ÑÑÐ²Ð¸Ñ Ð¿Ñавила. Ð ÑÑом ÑÑловии можно обÑаÑаÑÑÑÑ Ðº пÑевдооÑноÑениÑм NEW и/или OLD, коÑоÑÑе пÑедÑÑавлÑÑÑ Ñелевое оÑноÑение (но Ñ Ð¾ÑобÑм знаÑением).
ÐÑего еÑÑÑ ÑÑи ваÑианÑа ÑоÑмиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð´ÐµÑевÑев запÑоÑов Ð´Ð»Ñ Ð¿Ñавила Ñ Ð¾Ð´Ð½Ð¸Ð¼ дейÑÑвием.
- Ðез ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¿ÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² Ñежиме
ALSOилиINSTEAD деÑево запÑоÑа из дейÑÑÐ²Ð¸Ñ Ð¿Ñавила Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð½Ñм ÑÑловием иÑÑ Ð¾Ð´Ð½Ð¾Ð³Ð¾ деÑева
- С ÑÑловием пÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² Ñежиме
ALSO деÑево запÑоÑа из дейÑÑÐ²Ð¸Ñ Ð¿Ñавила Ñ ÑÑловием пÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ñавила и ÑÑловием, добавленнÑм из иÑÑ Ð¾Ð´Ð½Ð¾Ð³Ð¾ деÑева
- С ÑÑловием пÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² Ñежиме
INSTEAD деÑево запÑоÑа из дейÑÑÐ²Ð¸Ñ Ð¿Ñавила Ñ ÑÑловием пÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ñавила и ÑÑловием из иÑÑ Ð¾Ð´Ð½Ð¾Ð³Ð¾ деÑева; Ñакже добавлÑеÑÑÑ Ð¸ÑÑ Ð¾Ð´Ð½Ð¾Ðµ деÑево запÑоÑа Ñ ÑÑловием, обÑаÑнÑм ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¿ÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ñавила
ÐаконеÑ, Ð´Ð»Ñ Ð¿Ñавил ALSO в ÑпиÑок добавлÑеÑÑÑ Ð¸ÑÑ
одное деÑево запÑоÑа без изменений. Так как иÑÑ
одное деÑево запÑоÑа Ñакже добавлÑÑÑ ÑолÑко пÑавила INSTEAD Ñ ÑÑловиÑми пÑименениÑ, в иÑоге Ð´Ð»Ñ Ð¿Ñавила Ñ Ð¾Ð´Ð½Ð¸Ð¼ дейÑÑвием Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ полÑÑиÑÑ ÑолÑко одно или два деÑева запÑоÑов.
ÐÐ»Ñ Ð¿Ñавил ON INSERT иÑÑ
однÑй запÑÐ¾Ñ (еÑли он не пеÑекÑÑваеÑÑÑ Ñежимом INSTEAD) вÑполнÑеÑÑÑ Ð¿ÐµÑед дейÑÑвиÑми, добавленнÑми пÑавилами. ÐоÑÑÐ¾Ð¼Ñ ÑÑи дейÑÑÐ²Ð¸Ñ Ð¼Ð¾Ð³ÑÑ Ð²Ð¸Ð´ÐµÑÑ Ð²ÑÑавленнÑе ÑÑÑоки. Ðо Ð´Ð»Ñ Ð¿Ñавил ON UPDATE и ON DELETE иÑÑ
однÑй запÑÐ¾Ñ Ð²ÑполнÑеÑÑÑ Ð¿Ð¾Ñле дейÑÑвий, добавленнÑÑ
пÑавилами. ÐÑи Ñаком поÑÑдке ÑÑи дейÑÑÐ²Ð¸Ñ Ð±ÑдÑÑ Ð²Ð¸Ð´ÐµÑÑ ÑÑÑоки, подлежаÑие Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ ÑдалениÑ; инаÑе Ð±Ñ Ð´ÐµÐ¹ÑÑÐ²Ð¸Ñ Ð½Ðµ ÑабоÑали, не Ð½Ð°Ð¹Ð´Ñ ÑÑÑок, ÑооÑвеÑÑÑвÑÑÑиÑ
иÑ
ÑÑловиÑм пÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ (ÑÑи ÑÑÑоки Ñже бÑдÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ñ Ð¸Ð»Ð¸ ÑдаленÑ).
ÐеÑевÑÑ Ð·Ð°Ð¿ÑоÑов, полÑÑеннÑе из дейÑÑвий пÑавил, Ñнова попадаÑÑ Ð² ÑиÑÑÐµÐ¼Ñ Ð¿ÐµÑезапиÑи, где могÑÑ Ð¿ÑимениÑÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе пÑавила, добавлÑÑÑие или ÑбиÑаÑÑие деÑевÑÑ Ð·Ð°Ð¿ÑоÑа. ÐоÑÑÐ¾Ð¼Ñ Ð´ÐµÐ¹ÑÑÐ²Ð¸Ñ Ð¿Ñавила Ð´Ð¾Ð»Ð¶Ð½Ñ Ð²ÑполнÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð´ÑÑгого Ñипа или ÑабоÑаÑÑ Ñ Ð´ÑÑгим ÑезÑлÑÑиÑÑÑÑим оÑноÑением, инаÑе Ð²Ð¾Ð·Ð½Ð¸ÐºÐ½ÐµÑ Ð±ÐµÑконеÑÐ½Ð°Ñ ÑекÑÑÑиÑ. (СиÑÑема вÑÑвлÑÐµÑ Ð¿Ð¾Ð´Ð¾Ð±Ð½Ð¾Ðµ ÑекÑÑÑивное ÑазвоÑаÑивание пÑавил и вÑдаÑÑ Ð¾ÑибкÑ.)
ÐеÑевÑÑ Ð·Ð°Ð¿ÑоÑов, заданнÑе Ð´Ð»Ñ Ð´ÐµÐ¹ÑÑвий в ÑиÑÑемном каÑалоге pg_rewrite, пÑедÑÑавлÑÑÑ Ñобой ÑолÑко ÑаблонÑ. Так как они могÑÑ Ð¾Ð±ÑаÑаÑÑÑÑ Ðº ÑлеменÑам NEW и OLD в ÑпиÑке оÑноÑений, иÑ
можно бÑÐ´ÐµÑ Ð¸ÑполÑзоваÑÑ ÑолÑко поÑле некоÑоÑÑÑ
подÑÑановок. Ð ÑлÑÑае ÑÑÑлки на NEW ÑооÑвеÑÑÑвÑÑÑий ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¸ÑеÑÑÑ Ð² Ñелевом ÑпиÑке иÑÑ
одного запÑоÑа. ÐÑли он найден, ÑÑÑлка заменÑеÑÑÑ Ð²ÑÑажением ÑÑого ÑлеменÑа. РпÑоÑивном ÑлÑÑае NEW ознаÑÐ°ÐµÑ Ñо же Ñамое, ÑÑо и OLD (Ð´Ð»Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ UPDATE) или заменÑеÑÑÑ Ð·Ð½Ð°Ñением NULL (Ð´Ð»Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ INSERT). ÐÑбÑе ÑÑÑлки на OLD заменÑÑÑÑÑ ÑÑÑлкой на ÑÐ»ÐµÐ¼ÐµÐ½Ñ ÑезÑлÑÑиÑÑÑÑего оÑноÑÐµÐ½Ð¸Ñ Ð² ÑпиÑке оÑноÑений.
ÐоÑле Ñого как ÑиÑÑема пÑÐ¸Ð¼ÐµÐ½Ð¸Ñ Ð²Ñе пÑавила Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ, она пÑименÑÐµÑ Ð¿Ñавила пÑедÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ðº полÑÑÐµÐ½Ð½Ð¾Ð¼Ñ Ð´ÐµÑÐµÐ²Ñ (или деÑевÑÑм) запÑоÑа. ÐÑедÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ðµ могÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÑÑÑ Ð½Ð¾Ð²Ñе дейÑÑÐ²Ð¸Ñ Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ, поÑÑÐ¾Ð¼Ñ Ð½ÐµÑ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи пÑименÑÑÑ Ñакие пÑавила к ÑезÑлÑÑаÑÑ Ð¿ÐµÑезапиÑи пÑедÑÑавлениÑ.
39.4.1.1. ÐоÑаговÑй ÑÐ°Ð·Ð±Ð¾Ñ Ð¿ÐµÑвого пÑавила #
ÐÑедположим, ÑÑо нам нÑжно оÑÑлеживаÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² ÑÑолбÑе sl_avail ÑаблиÑÑ shoelace_data. ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ ÑоздаÑÑ ÑаблиÑÑ Ð´Ð»Ñ Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¶ÑÑнала и пÑавило, коÑоÑое бÑÐ´ÐµÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÑÑÑ Ð² Ð½ÐµÑ Ð·Ð°Ð¿Ð¸Ñи по ÑÑловиÑ, когда Ð´Ð»Ñ shoelace_data вÑполнÑеÑÑÑ UPDATE.
CREATE TABLE shoelace_log (
sl_name text, -- ÑнÑÑки, колиÑеÑÑво коÑоÑÑÑ
изменилоÑÑ
sl_avail integer, -- новое колиÑеÑÑво
log_who text, -- кÑо изменил
log_when timestamp -- когда
);
CREATE RULE log_shoelace AS ON UPDATE TO shoelace_data
WHERE NEW.sl_avail <> OLD.sl_avail
DO INSERT INTO shoelace_log VALUES (
NEW.sl_name,
NEW.sl_avail,
current_user,
current_timestamp
);ТепеÑÑ, еÑли кÑо-Ñо вÑполниÑ:
UPDATE shoelace_data SET sl_avail = 6 WHERE sl_name = 'sl7';
Ð¼Ñ Ñвидим в ÑаблиÑе жÑÑнала:
SELECT * FROM shoelace_log; sl_name | sl_avail | log_who | log_when ---------+----------+---------+---------------------------------- sl7 | 6 | Al | Tue Oct 20 16:14:45 1998 MET DST (1 row)
Ðменно ÑÑо нам и нÑжно. ÐÑи ÑÑом внÑÑÑи пÑоиÑÑ Ð¾Ð´Ð¸Ñ ÑледÑÑÑее. ÐнализаÑÐ¾Ñ Ð·Ð°Ð¿ÑоÑа ÑоздаÑÑ Ð´ÐµÑево:
UPDATE shoelace_data SET sl_avail = 6 FROM shoelace_data shoelace_data WHERE shoelace_data.sl_name = 'sl7';
Ð ÑиÑÑемном каÑалоге наÑ
одиÑÑÑ Ð¿Ñавило log_shoelace, наÑÑÑоенное на изменение (ON UPDATE) Ñ ÑÑловием пÑименениÑ:
NEW.sl_avail <> OLD.sl_avail
и дейÑÑвием:
INSERT INTO shoelace_log VALUES (
new.sl_name, new.sl_avail,
current_user, current_timestamp )
FROM shoelace_data new, shoelace_data old; (ÐÑо вÑглÑÐ´Ð¸Ñ Ð½ÐµÑколÑко ÑÑÑанно, Ñак как обÑÑно нелÑÐ·Ñ Ð½Ð°Ð¿Ð¸ÑаÑÑ INSERT ... VALUES ... FROM. ÐÑедложение FROM здеÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¾, пÑоÑÑо ÑÑÐ¾Ð±Ñ Ð¿Ð¾ÐºÐ°Ð·Ð°ÑÑ, ÑÑо в деÑеве запÑоÑа Ð´Ð»Ñ ÑÑÑлок new и old еÑÑÑ ÑлеменÑÑ Ð² ÑпиÑке оÑноÑений. Ðни необÑ
Ð¾Ð´Ð¸Ð¼Ñ Ð´Ð»Ñ Ñого, ÑÑÐ¾Ð±Ñ Ðº ним могли обÑаÑаÑÑÑÑ Ð¿ÐµÑеменнÑе в деÑеве запÑоÑа ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ INSERT.)
Так как ÑÑо пÑавило ALSO Ñ ÑÑловием пÑименениÑ, ÑиÑÑема пÑавил должна вÑдаÑÑ Ð´Ð²Ð° деÑева запÑоÑов: изменÑнное дейÑÑвие пÑавила и иÑÑ
одное деÑево запÑоÑа. Ðа пеÑвом Ñаге ÑпиÑок оÑноÑений иÑÑ
одного запÑоÑа вÑÑавлÑеÑÑÑ Ð² деÑево дейÑÑÐ²Ð¸Ñ Ð¿Ñавила и полÑÑаеÑÑÑ:
INSERT INTO shoelace_log VALUES (
new.sl_name, new.sl_avail,
current_user, current_timestamp )
FROM shoelace_data new, shoelace_data old,
shoelace_data shoelace_data; Ðа вÑоÑом Ñаге в ÑÑо деÑево добавлÑеÑÑÑ ÑÑловие пÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ñавила, Ñак ÑÑо ÑезÑлÑÑиÑÑÑÑий Ð½Ð°Ð±Ð¾Ñ Ð¾Ð³ÑаниÑиваеÑÑÑ ÑÑÑоками, в коÑоÑÑÑ
менÑеÑÑÑ sl_avail:
INSERT INTO shoelace_log VALUES (
new.sl_name, new.sl_avail,
current_user, current_timestamp )
FROM shoelace_data new, shoelace_data old,
shoelace_data shoelace_data
WHERE new.sl_avail <> old.sl_avail; (ÐÑо вÑглÑÐ´Ð¸Ñ ÐµÑÑ Ð±Ð¾Ð»ÐµÐµ ÑÑÑанно, Ð²ÐµÐ´Ñ Ð² INSERT ... VALUES не запиÑÑваеÑÑÑ Ð¸ пÑедложение WHERE, но планиÑовÑик и иÑполниÑÐµÐ»Ñ Ð½Ðµ иÑпÑÑÑваÑÑ Ð·Ð°ÑÑÑднений Ñ ÑÑим. Ðни вÑÑ Ñавно Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¿Ð¾Ð´Ð´ÐµÑживаÑÑ ÑÑÑ ÑÑнкÑионалÑноÑÑÑ Ð´Ð»Ñ INSERT ... SELECT.)
Ðа ÑÑеÑÑем Ñаге добавлÑеÑÑÑ ÑÑловие иÑÑ Ð¾Ð´Ð½Ð¾Ð³Ð¾ деÑева, ÑÑо еÑÑ Ð±Ð¾Ð»ÑÑе огÑаниÑÐ¸Ð²Ð°ÐµÑ ÑезÑлÑÑиÑÑÑÑий набоÑ, оÑÑавлÑÑ Ð² нÑм ÑолÑко ÑÑÑоки, коÑоÑÑе заÑÑонÑл Ð±Ñ Ð¸ÑÑ Ð¾Ð´Ð½Ñй запÑоÑ:
INSERT INTO shoelace_log VALUES (
new.sl_name, new.sl_avail,
current_user, current_timestamp )
FROM shoelace_data new, shoelace_data old,
shoelace_data shoelace_data
WHERE new.sl_avail <> old.sl_avail
AND shoelace_data.sl_name = 'sl7';Ðа ÑеÑвÑÑÑом Ñаге ÑÑÑлки на NEW заменÑÑÑÑÑ ÑлеменÑами вÑÑ
одного ÑпиÑка из иÑÑ
одного деÑева запÑоÑа или пеÑеменнÑми из ÑезÑлÑÑиÑÑÑÑего оÑноÑениÑ:
INSERT INTO shoelace_log VALUES (
shoelace_data.sl_name, 6,
current_user, current_timestamp )
FROM shoelace_data new, shoelace_data old,
shoelace_data shoelace_data
WHERE 6 <> old.sl_avail
AND shoelace_data.sl_name = 'sl7';Ðа поÑледнем, пÑÑом Ñаге ÑÑÑлки на OLD заменÑÑÑÑÑ ÑÑÑлками на ÑезÑлÑÑиÑÑÑÑее оÑноÑение:
INSERT INTO shoelace_log VALUES (
shoelace_data.sl_name, 6,
current_user, current_timestamp )
FROM shoelace_data new, shoelace_data old,
shoelace_data shoelace_data
WHERE 6 <> shoelace_data.sl_avail
AND shoelace_data.sl_name = 'sl7';ÐÐ¾Ñ Ð¸ вÑÑ. Так как пÑавило дейÑÑвÑÐµÑ Ð² Ñежиме ALSO, Ð¼Ñ Ñакже вÑводим иÑÑ
одное деÑево запÑоÑа. Таким обÑазом, ÑиÑÑема пÑавил вÑдаÑÑ ÑпиÑок Ñ Ð´Ð²ÑÐ¼Ñ Ð´ÐµÑевÑÑми запÑоÑов, ÑооÑвеÑÑÑвÑÑÑими ÑÑим опеÑаÑоÑам:
INSERT INTO shoelace_log VALUES (
shoelace_data.sl_name, 6,
current_user, current_timestamp )
FROM shoelace_data
WHERE 6 <> shoelace_data.sl_avail
AND shoelace_data.sl_name = 'sl7';
UPDATE shoelace_data SET sl_avail = 6
WHERE sl_name = 'sl7';Ðни вÑполнÑÑÑÑÑ Ð² показанном поÑÑдке и именно ÑÑо должно делаÑÑ Ð´Ð°Ð½Ð½Ð¾Ðµ пÑавило.
ÐлагодаÑÑ Ð·Ð°Ð¼ÐµÐ½Ð°Ð¼ и добавленнÑм ÑÑловиÑм в жÑÑнал не добавиÑÑÑ Ð·Ð°Ð¿Ð¸ÑÑ, напÑимеÑ, пÑи Ñаком иÑÑ Ð¾Ð´Ð½Ð¾Ð¼ запÑоÑе:
UPDATE shoelace_data SET sl_color = 'green' WHERE sl_name = 'sl7';
Ð ÑÑом ÑлÑÑае иÑÑ
одное деÑево запÑоÑа не ÑодеÑÐ¶Ð¸Ñ ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð²ÑÑ
одного ÑпиÑка Ð´Ð»Ñ sl_avail, Ñак ÑÑо NEW.sl_avail бÑÐ´ÐµÑ Ð·Ð°Ð¼ÐµÐ½ÐµÐ½Ð¾ пеÑеменной shoelace_data.sl_avail. Таким обÑазом, дополниÑелÑÐ½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°, ÑÐ¾Ð·Ð´Ð°Ð½Ð½Ð°Ñ Ð¿Ñавилом, бÑÐ´ÐµÑ Ñакой:
INSERT INTO shoelace_log VALUES (
shoelace_data.sl_name, shoelace_data.sl_avail,
current_user, current_timestamp )
FROM shoelace_data
WHERE shoelace_data.sl_avail <> shoelace_data.sl_avail
AND shoelace_data.sl_name = 'sl7';ÐÑо ÑÑловие пÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ðµ бÑÐ´ÐµÑ Ð²ÑполнÑÑÑÑÑ Ð½Ð¸ÐºÐ¾Ð³Ð´Ð°.
ÐÑо Ñакже бÑÐ´ÐµÑ ÑабоÑаÑÑ, еÑли иÑÑ Ð¾Ð´Ð½Ñй запÑÐ¾Ñ Ð¸Ð·Ð¼ÐµÐ½ÑÐµÑ Ð½ÐµÑколÑко ÑÑÑок. Так, еÑли кÑо-Ñо вÑÐ¿Ð¾Ð»Ð½Ð¸Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ:
UPDATE shoelace_data SET sl_avail = 0 WHERE sl_color = 'black';
ÑакÑиÑеÑки бÑдÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ñ ÑеÑÑÑе ÑÑÑоки (sl1, sl2, sl3 и sl4). Ðо Ð´Ð»Ñ sl3 знаÑение sl_avail = 0. Ð ÑÑом ÑлÑÑае ÑÑловие иÑÑ
одного деÑева дÑÑгое, Ñак ÑÑо ÑÑо пÑавило вÑдаÑÑ Ñакое дополниÑелÑное деÑево запÑоÑа:
INSERT INTO shoelace_log
SELECT shoelace_data.sl_name, 0,
current_user, current_timestamp
FROM shoelace_data
WHERE 0 <> shoelace_data.sl_avail
AND shoelace_data.sl_color = 'black';. С Ñаким деÑевом запÑоÑа в жÑÑнал опÑеделÑнно бÑдÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ñ ÑÑи запиÑи. Ð ÑÑо абÑолÑÑно пÑавилÑно.
ÐдеÑÑ Ð¼Ñ Ð²Ð¸Ð´Ð¸Ð¼, поÑÐµÐ¼Ñ Ð²Ð°Ð¶Ð½Ð¾, ÑÑÐ¾Ð±Ñ Ð¸ÑÑ
одное деÑево запÑоÑа вÑполнÑлоÑÑ Ð² конÑе. ÐÑли Ð±Ñ Ð¾Ð¿ÐµÑаÑÐ¾Ñ UPDATE вÑполнилÑÑ ÑнаÑала, вÑе ÑÑÑоки Ñже полÑÑили Ð±Ñ Ð½ÑлевÑе знаÑениÑ, Ñак ÑÑо запиÑÑваÑÑий в жÑÑнал INSERT не наÑÑл Ð±Ñ ÑÑÑок, в коÑоÑÑÑ
0 <> shoelace_data.sl_avail.
39.4.2. СоÑеÑание Ñ Ð¿ÑедÑÑавлениÑми #
ÐÑÑÑ Ð¾Ð´Ð¸Ð½ пÑоÑÑой ваÑÐ¸Ð°Ð½Ñ Ð·Ð°ÑиÑиÑÑÑÑ Ð¾Ñ Ñанее ÑпомÑнÑÑой возможноÑÑи вÑполнÑÑÑ INSERT, UPDATE или DELETE Ð´Ð»Ñ Ð¿ÑедÑÑавлений, когда ÑÑо нежелаÑелÑно â ÑоздаÑÑ Ð¿Ñавила, пÑоÑÑо оÑбÑаÑÑваÑÑие деÑевÑÑ ÑÑиÑ
запÑоÑов. РнаÑем ÑлÑÑае они бÑдÑÑ Ð²ÑглÑдеÑÑ Ñак:
CREATE RULE shoe_ins_protect AS ON INSERT TO shoe
DO INSTEAD NOTHING;
CREATE RULE shoe_upd_protect AS ON UPDATE TO shoe
DO INSTEAD NOTHING;
CREATE RULE shoe_del_protect AS ON DELETE TO shoe
DO INSTEAD NOTHING; ÐÑли ÑепеÑÑ ÐºÑо-Ñо попÑÑаеÑÑÑ Ð²ÑполниÑÑ Ð¾Ð´Ð½Ñ Ð¸Ð· ÑÑиÑ
опеÑаÑий Ñ Ð¿ÑедÑÑавлением shoe, ÑиÑÑема пÑавил пÑÐ¸Ð¼ÐµÐ½Ð¸Ñ ÑÑи пÑавила. Так как ÑÑо пÑавила без дейÑÑвий в Ñежиме INSTEAD, ÑезÑлÑÑиÑÑÑÑий ÑпиÑок деÑевÑев запÑоÑа бÑÐ´ÐµÑ Ð¿ÑÑÑ Ð¸ веÑÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð°Ð½Ð½ÑлиÑÑеÑÑÑ, Ñак ÑÑо поÑле ÑабоÑÑ ÑиÑÑÐµÐ¼Ñ Ð¿Ñавил бÑÐ´ÐµÑ Ð½ÐµÑего опÑимизиÑоваÑÑ Ð¸ вÑполнÑÑÑ.
Ðолее ÑложнÑй ваÑÐ¸Ð°Ð½Ñ â иÑполÑзоваÑÑ ÑиÑÑÐµÐ¼Ñ Ð¿Ñавил Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ñавил, пÑеобÑазÑÑÑиÑ
деÑево запÑоÑа в вÑполнÑÑÑее нÑжнÑÑ Ð¾Ð¿ÐµÑаÑÐ¸Ñ Ñ ÑеалÑнÑми ÑаблиÑами. ЧÑÐ¾Ð±Ñ ÑеализоваÑÑ ÑÑо Ñ Ð¿ÑедÑÑавлением shoelace, Ð¼Ñ Ñоздадим ÑледÑÑÑие пÑавила:
CREATE RULE shoelace_ins AS ON INSERT TO shoelace
DO INSTEAD
INSERT INTO shoelace_data VALUES (
NEW.sl_name,
NEW.sl_avail,
NEW.sl_color,
NEW.sl_len,
NEW.sl_unit
);
CREATE RULE shoelace_upd AS ON UPDATE TO shoelace
DO INSTEAD
UPDATE shoelace_data
SET sl_name = NEW.sl_name,
sl_avail = NEW.sl_avail,
sl_color = NEW.sl_color,
sl_len = NEW.sl_len,
sl_unit = NEW.sl_unit
WHERE sl_name = OLD.sl_name;
CREATE RULE shoelace_del AS ON DELETE TO shoelace
DO INSTEAD
DELETE FROM shoelace_data
WHERE sl_name = OLD.sl_name;ÐÑли Ð²Ñ Ñ
оÑиÑе поддеÑживаÑÑ Ñакже запÑоÑÑ Ðº пÑедÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ RETURNING, вам надо ÑоздаÑÑ Ð¿Ñавила Ñ Ð¿ÑедложениÑми RETURNING, коÑоÑÑе бÑдÑÑ Ð²ÑÑиÑлÑÑÑ ÑÑÑоки пÑедÑÑавлениÑ. ÐÑо обÑÑно доволÑно ÑÑивиалÑно Ð´Ð»Ñ Ð¿ÑедÑÑавлений Ñ Ð¾Ð´Ð½Ð¾Ð¹ нижележаÑей ÑаблиÑей, но неÑколÑко заÑÑÑдниÑелÑно Ð´Ð»Ñ Ð¿ÑедÑÑавлений Ñ Ñоединением, ÑакиÑ
как shoelace. ÐапÑимеÑ, Ð´Ð»Ñ INSERT ÑÑо бÑÐ´ÐµÑ Ð²ÑглÑдеÑÑ Ñак:
CREATE RULE shoelace_ins AS ON INSERT TO shoelace
DO INSTEAD
INSERT INTO shoelace_data VALUES (
NEW.sl_name,
NEW.sl_avail,
NEW.sl_color,
NEW.sl_len,
NEW.sl_unit
)
RETURNING
shoelace_data.*,
(SELECT shoelace_data.sl_len * u.un_fact
FROM unit u WHERE shoelace_data.sl_unit = u.un_name); ÐамеÑÑÑе, ÑÑо ÑÑо одно пÑавило поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð·Ð°Ð¿ÑоÑÑ Ð¸ INSERT, и INSERT RETURNING к ÑÑÐ¾Ð¼Ñ Ð¿ÑедÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ â пÑедложение RETURNING пÑоÑÑо игноÑиÑÑеÑÑÑ Ð¿Ñи обÑÑном INSERT.
ТепеÑÑ Ð¿Ñедположим, ÑÑо на ÑабÑÐ¸ÐºÑ Ð¿ÑибÑÐ²Ð°ÐµÑ Ð¿Ð°ÑÑÐ¸Ñ ÑнÑÑков Ñ Ð¾Ð±ÑÑмной ÑопÑоводиÑелÑной накладной. Ðо Ð²Ñ Ð½Ðµ Ñ
оÑиÑе вÑÑÑнÑÑ Ð²Ð½Ð¾ÑиÑÑ Ð¿Ð¾ одной запиÑи в пÑедÑÑавление shoelace. ÐмеÑÑо ÑÑого можно ÑоздаÑÑ Ð´Ð²Ðµ маленÑкие ÑаблиÑÑ: в пеÑвÑÑ Ð²Ñ Ð±ÑдеÑе вÑÑавлÑÑÑ Ð·Ð°Ð¿Ð¸Ñи из накладной, а вÑоÑÐ°Ñ Ð¿ÑигодиÑÑÑ Ð´Ð»Ñ ÑпеÑиалÑного пÑиÑма. ÐÐ»Ñ ÑÑого Ð¼Ñ Ð²Ñполним ÑледÑÑÑие командÑ:
CREATE TABLE shoelace_arrive (
arr_name text,
arr_quant integer
);
CREATE TABLE shoelace_ok (
ok_name text,
ok_quant integer
);
CREATE RULE shoelace_ok_ins AS ON INSERT TO shoelace_ok
DO INSTEAD
UPDATE shoelace
SET sl_avail = sl_avail + NEW.ok_quant
WHERE sl_name = NEW.ok_name; ТепеÑÑ Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе наполниÑÑ ÑаблиÑÑ shoelace_arrive даннÑми о поÑÑÑпивÑиÑ
ÑнÑÑкаÑ
из накладной:
SELECT * FROM shoelace_arrive; arr_name | arr_quant ----------+----------- sl3 | 10 sl6 | 20 sl8 | 20 (3 rows)
ÐзглÑниÑе на ÑекÑÑие даннÑе:
SELECT * FROM shoelace; sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm ----------+----------+----------+--------+---------+----------- sl1 | 5 | black | 80 | cm | 80 sl2 | 6 | black | 100 | cm | 100 sl7 | 6 | brown | 60 | cm | 60 sl3 | 0 | black | 35 | inch | 88.9 sl4 | 8 | black | 40 | inch | 101.6 sl8 | 1 | brown | 40 | inch | 101.6 sl5 | 4 | brown | 1 | m | 100 sl6 | 0 | brown | 0.9 | m | 90 (8 rows)
ТепеÑÑ Ð¿ÐµÑемеÑÑиÑе пÑибÑвÑие ÑнÑÑки во вÑоÑÑÑ ÑаблиÑÑ:
INSERT INTO shoelace_ok SELECT * FROM shoelace_arrive;
ÐÑовеÑÑÑе, ÑÑо полÑÑилоÑÑ:
SELECT * FROM shoelace ORDER BY sl_name; sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm ----------+----------+----------+--------+---------+----------- sl1 | 5 | black | 80 | cm | 80 sl2 | 6 | black | 100 | cm | 100 sl7 | 6 | brown | 60 | cm | 60 sl4 | 8 | black | 40 | inch | 101.6 sl3 | 10 | black | 35 | inch | 88.9 sl8 | 21 | brown | 40 | inch | 101.6 sl5 | 4 | brown | 1 | m | 100 sl6 | 20 | brown | 0.9 | m | 90 (8 rows) SELECT * FROM shoelace_log; sl_name | sl_avail | log_who| log_when ---------+----------+--------+---------------------------------- sl7 | 6 | Al | Tue Oct 20 19:14:45 1998 MET DST sl3 | 10 | Al | Tue Oct 20 19:25:16 1998 MET DST sl6 | 20 | Al | Tue Oct 20 19:25:16 1998 MET DST sl8 | 21 | Al | Tue Oct 20 19:25:16 1998 MET DST (4 rows)
ЧÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ ÑÑи ÑезÑлÑÑаÑÑ Ð¸Ð· одного INSERT ... SELECT, бÑла пÑоделана болÑÑÐ°Ñ ÑабоÑа. ÐÑ Ð¿Ð¾Ð´Ñобно опиÑем вÑÑ Ð¿ÑеобÑазование деÑева запÑоÑов в пÑодолжении ÑÑой главÑ. ÐаÑнÑм Ñ Ð´ÐµÑева, вÑданного анализаÑоÑом запÑоÑа:
INSERT INTO shoelace_ok SELECT shoelace_arrive.arr_name, shoelace_arrive.arr_quant FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok;
ТепеÑÑ Ð¿ÑименÑеÑÑÑ Ð¿ÐµÑвое пÑавило shoelace_ok_ins, ÑоздаÑÑее Ñакое деÑево:
UPDATE shoelace
SET sl_avail = shoelace.sl_avail + shoelace_arrive.arr_quant
FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok,
shoelace_ok old, shoelace_ok new,
shoelace shoelace
WHERE shoelace.sl_name = shoelace_arrive.arr_name; и оÑбÑаÑÑваÑÑее иÑÑ
однÑй INSERT в shoelace_ok. ÐÑÐ¾Ñ Ð¿ÐµÑепиÑаннÑй запÑÐ¾Ñ Ñнова поÑÑÑÐ¿Ð°ÐµÑ Ð² ÑиÑÑÐµÐ¼Ñ Ð¿Ñавил и вÑоÑое пÑименÑемое пÑавило shoelace_upd вÑдаÑÑ:
UPDATE shoelace_data
SET sl_name = shoelace.sl_name,
sl_avail = shoelace.sl_avail + shoelace_arrive.arr_quant,
sl_color = shoelace.sl_color,
sl_len = shoelace.sl_len,
sl_unit = shoelace.sl_unit
FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok,
shoelace_ok old, shoelace_ok new,
shoelace shoelace, shoelace old,
shoelace new, shoelace_data shoelace_data
WHERE shoelace.sl_name = shoelace_arrive.arr_name
AND shoelace_data.sl_name = shoelace.sl_name; ÐÑо Ñоже пÑавило INSTEAD, Ñак ÑÑо пÑедÑдÑÑее деÑево запÑоÑа оÑбÑаÑÑваеÑÑÑ. ÐамеÑÑÑе, ÑÑо ÑÑÐ¾Ñ Ð·Ð°Ð¿ÑÐ¾Ñ Ð¿Ð¾-пÑÐµÐ¶Ð½ÐµÐ¼Ñ Ð¸ÑполÑзÑÐµÑ Ð¿ÑедÑÑавление shoelace. Ðо ÑиÑÑема пÑавил еÑÑ Ð½Ðµ законÑила ÑÐ²Ð¾Ñ ÑабоÑÑ, она пÑÐ¾Ð´Ð¾Ð»Ð¶Ð°ÐµÑ Ð¸ пÑименÑÐµÑ Ð¿Ñавило _RETURN, Ñак ÑÑо Ð¼Ñ Ð¿Ð¾Ð»ÑÑаем:
UPDATE shoelace_data
SET sl_name = s.sl_name,
sl_avail = s.sl_avail + shoelace_arrive.arr_quant,
sl_color = s.sl_color,
sl_len = s.sl_len,
sl_unit = s.sl_unit
FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok,
shoelace_ok old, shoelace_ok new,
shoelace shoelace, shoelace old,
shoelace new, shoelace_data shoelace_data,
shoelace old, shoelace new,
shoelace_data s, unit u
WHERE s.sl_name = shoelace_arrive.arr_name
AND shoelace_data.sl_name = s.sl_name; ÐаконеÑ, пÑименÑеÑÑÑ Ð¿Ñавило log_shoelace и вÑдаÑÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑное деÑево запÑоÑа:
INSERT INTO shoelace_log
SELECT s.sl_name,
s.sl_avail + shoelace_arrive.arr_quant,
current_user,
current_timestamp
FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok,
shoelace_ok old, shoelace_ok new,
shoelace shoelace, shoelace old,
shoelace new, shoelace_data shoelace_data,
shoelace old, shoelace new,
shoelace_data s, unit u,
shoelace_data old, shoelace_data new
shoelace_log shoelace_log
WHERE s.sl_name = shoelace_arrive.arr_name
AND shoelace_data.sl_name = s.sl_name
AND (s.sl_avail + shoelace_arrive.arr_quant) <> s.sl_avail;ТепеÑÑ, обÑабоÑав вÑе пÑавила, ÑиÑÑема пÑавил вÑдаÑÑ Ð¿Ð¾ÑÑÑоеннÑе деÑевÑÑ Ð·Ð°Ð¿ÑоÑов.
РиÑоге Ð¼Ñ Ð¿Ð¾Ð»ÑÑаем два деÑева запÑоÑов, ÑавнознаÑнÑе ÑледÑÑÑим опеÑаÑоÑам SQL:
INSERT INTO shoelace_log
SELECT s.sl_name,
s.sl_avail + shoelace_arrive.arr_quant,
current_user,
current_timestamp
FROM shoelace_arrive shoelace_arrive, shoelace_data shoelace_data,
shoelace_data s
WHERE s.sl_name = shoelace_arrive.arr_name
AND shoelace_data.sl_name = s.sl_name
AND s.sl_avail + shoelace_arrive.arr_quant <> s.sl_avail;
UPDATE shoelace_data
SET sl_avail = shoelace_data.sl_avail + shoelace_arrive.arr_quant
FROM shoelace_arrive shoelace_arrive,
shoelace_data shoelace_data,
shoelace_data s
WHERE s.sl_name = shoelace_arrive.sl_name
AND shoelace_data.sl_name = s.sl_name;Ð ÑезÑлÑÑаÑе вÑÑ Ð¾Ð¿ÐµÑаÑиÑ, в Ñ Ð¾Ð´Ðµ коÑоÑой даннÑе, поÑÑÑпаÑÑие из одного оÑноÑениÑ, вÑÑавлÑÑÑÑÑ Ð² дÑÑгое, вÑÑавка пÑеобÑазÑеÑÑÑ Ð² изменение ÑÑеÑÑего, ÑÑо заÑем ÑÑановиÑÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸ÐµÐ¼ ÑеÑвÑÑÑого, и запиÑÑ Ð¾Ð± ÑÑом изменении добавлÑеÑÑÑ Ð² пÑÑое, ÑводиÑÑÑ Ðº двÑм запÑоÑам.
ÐдеÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ замеÑиÑÑ Ð¼Ð°Ð»ÐµÐ½ÑкÑÑ Ð½Ðµ оÑÐµÐ½Ñ ÐºÑаÑивÑÑ Ð´ÐµÑалÑ. Ðак видно, в ÑÑиÑ
двÑÑ
запÑоÑаÑ
ÑаблиÑа shoelace_data ÑигÑÑиÑÑÐµÑ Ð² ÑпиÑке оÑноÑений дваждÑ, Ñогда как опÑеделÑнно доÑÑаÑоÑно и одного вÑ
ождениÑ. ÐланиÑовÑик не Ð¿Ð¾Ð½Ð¸Ð¼Ð°ÐµÑ ÑÑого и поÑÑÐ¾Ð¼Ñ Ð´Ð»Ñ Ð´ÐµÑева запÑоÑа INSERT, вÑданного ÑиÑÑемой пÑавил, бÑÐ´ÐµÑ Ð¿Ð¾Ð»ÑÑен Ñакой план:
Nested Loop
-> Merge Join
-> Seq Scan
-> Sort
-> Seq Scan on s
-> Seq Scan
-> Sort
-> Seq Scan on shoelace_arrive
-> Seq Scan on shoelace_data
Тогда как без лиÑнего ÑлеменÑа в ÑпиÑке оÑноÑений Ð¼Ñ Ð¿Ð¾Ð»ÑÑили бÑ:
Merge Join
-> Seq Scan
-> Sort
-> Seq Scan on s
-> Seq Scan
-> Sort
-> Seq Scan on shoelace_arrive
ÐÑи ÑÑом в жÑÑнале оказалиÑÑ Ð±Ñ ÑоÑно Ñакие же запиÑи. Таким обÑазом, пÑименение пÑавил повлекло дополниÑелÑное ÑканиÑование ÑаблиÑÑ shoelace_data, в коÑоÑом не бÑло никакой необÑ
одимоÑÑи. Ð Ñакое же избÑÑоÑное ÑканиÑование вÑполнÑеÑÑÑ ÐµÑÑ Ñаз в UPDATE. ÐÑнеÑиÑеÑÑ Ðº ÑÑÐ¾Ð¼Ñ Ñ Ð¿Ð¾Ð½Ð¸Ð¼Ð°Ð½Ð¸ÐµÐ¼, Ð²ÐµÐ´Ñ ÑделаÑÑ Ð²ÑÑ ÑÑо возможнÑм в пÑинÑипе бÑло дейÑÑвиÑелÑно Ñложно.
РнаконеÑ, еÑÑ Ð¾Ð´Ð½Ð°, завеÑÑаÑÑÐ°Ñ Ð´ÐµÐ¼Ð¾Ð½ÑÑÑаÑÐ¸Ñ ÑиÑÑÐµÐ¼Ñ Ð¿Ñавил Postgres Pro и вÑей ÐµÑ Ð¼Ð¾Ñи. ÐÑедположим, ÑÑо Ð²Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ð»Ð¸ в Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ ÑнÑÑки Ñ ÑкÑÑÑаоÑдинаÑнÑми ÑвеÑами:
INSERT INTO shoelace VALUES ('sl9', 0, 'pink', 35.0, 'inch', 0.0);
INSERT INTO shoelace VALUES ('sl10', 1000, 'magenta', 40.0, 'inch', 0.0); ÐавайÑе Ñоздадим пÑедÑÑавление, ÑÑÐ¾Ð±Ñ ÑбедиÑÑÑÑ, ÑÑо ÑнÑÑки (запиÑи в shoelace) не подÑ
одÑÑ Ð½Ð¸ к каким ÑÑÑлÑм. Ðно бÑÐ´ÐµÑ Ð¾Ð¿Ñеделено Ñак:
CREATE VIEW shoelace_mismatch AS
SELECT * FROM shoelace WHERE NOT EXISTS
(SELECT shoename FROM shoe WHERE slcolor = sl_color);ЧеÑез него Ð¼Ñ Ð¿Ð¾Ð»ÑÑаем наÑи запиÑи:
SELECT * FROM shoelace_mismatch; sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm ---------+----------+----------+--------+---------+----------- sl9 | 0 | pink | 35 | inch | 88.9 sl10 | 1000 | magenta | 40 | inch | 101.6
ТепеÑÑ Ð¼Ñ Ñ Ð¾Ñим, ÑÑÐ¾Ð±Ñ ÑнÑÑки, коÑоÑÑе ни к ÑÐµÐ¼Ñ Ð½Ðµ Ð¿Ð¾Ð´Ñ Ð¾Ð´ÑÑ, ÑдалÑлиÑÑ Ð¸Ð· Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ . ЧÑÐ¾Ð±Ñ Ð½ÐµÐ¼Ð½Ð¾Ð³Ð¾ ÑÑложниÑÑ Ð·Ð°Ð´Ð°ÑÑ Ð´Ð»Ñ Postgres Pro, Ð¼Ñ Ð½Ðµ бÑдем ÑдалÑÑÑ Ð¸Ñ Ð½ÐµÐ¿Ð¾ÑÑедÑÑвенно из ÑаблиÑÑ. ÐмеÑÑо ÑÑого Ð¼Ñ Ñоздадим еÑÑ Ð¾Ð´Ð½Ð¾ пÑедÑÑавление:
CREATE VIEW shoelace_can_delete AS
SELECT * FROM shoelace_mismatch WHERE sl_avail = 0;Ð Ñдалим Ð¸Ñ Ñак:
DELETE FROM shoelace WHERE EXISTS
(SELECT * FROM shoelace_can_delete
WHERE sl_name = shoelace.sl_name);Ð ÑезÑлÑÑаÑе полÑÑим:
SELECT * FROM shoelace; sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm ---------+----------+----------+--------+---------+----------- sl1 | 5 | black | 80 | cm | 80 sl2 | 6 | black | 100 | cm | 100 sl7 | 6 | brown | 60 | cm | 60 sl4 | 8 | black | 40 | inch | 101.6 sl3 | 10 | black | 35 | inch | 88.9 sl8 | 21 | brown | 40 | inch | 101.6 sl10 | 1000 | magenta | 40 | inch | 101.6 sl5 | 4 | brown | 1 | m | 100 sl6 | 20 | brown | 0.9 | m | 90 (9 rows)
Так запÑÐ¾Ñ DELETE Ð´Ð»Ñ Ð¿ÑедÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ Ð¾Ð³ÑаниÑиваÑÑим ÑÑловием-подзапÑоÑом, иÑполÑзÑÑÑим в ÑовокÑпноÑÑи 4 вложеннÑÑ
/ÑоединÑннÑÑ
пÑедÑÑавлениÑ, Ñ Ð¾Ð´Ð½Ð¸Ð¼ из коÑоÑÑÑ
Ñоже ÑвÑзано ÑÑловие Ñ Ð¿Ð¾Ð´Ð·Ð°Ð¿ÑоÑом, задейÑÑвÑÑÑим пÑедÑÑавление, и где иÑполÑзÑÑÑÑÑ Ð²ÑÑиÑлÑемÑе ÑÑолбÑÑ Ð¿ÑедÑÑавлений, пеÑепиÑÑваеÑÑÑ Ð¸ пÑеобÑазÑеÑÑÑ Ð² одно деÑево запÑоÑа, коÑоÑое ÑдалÑÐµÑ ÑÑебÑемÑе даннÑе из ÑеалÑной ÑаблиÑÑ.
Ðа пÑакÑике ÑиÑÑаÑии, когда Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð° ÑÐ°ÐºÐ°Ñ ÑÐ»Ð¾Ð¶Ð½Ð°Ñ ÐºÐ¾Ð½ÑÑÑÑкÑиÑ, вÑÑÑеÑаÑÑÑÑ Ð´Ð¾Ð²Ð¾Ð»Ñно Ñедко, но Ñем не менее пÑиÑÑно оÑознаваÑÑ, ÑÑо вÑÑ ÑÑо возможно и ÑабоÑаеÑ.