2010-07-19 11 views
5

पर बाधाओं को हिट करता है मैं दो तालिकाओं से पंक्तियों को हटाना चाहता हूं, जो एक दूसरे पर निर्भरता बाधाओं के एक सेट के माध्यम से निर्भरता रखते हैं। इस पोस्ट को सरल बनाने के लिए, मैंने एक साधारण डीबी स्कीमा का मज़ाक उड़ाया है।PostgreSQL 'Deferrable Delete' अभी भी हटाएं

मैं कुछ एसक्यूएल लेनदेन/डीबी पैच के अंदर 'delete_from_me', कुछ तालिका से प्रविष्टियों को हटाने की उम्मीद कर रहा हूं। पकड़ है, मैं लिंक को खोने से पहले, दूसरी तालिका 'constraining_table' से किसी चयन के आधार पर हटाना चाहता हूं।

tab-quarantine=> \d delete_from_me 
     Table "public.delete_from_me" 
    Column |  Type  | Modifiers 
-----------+-------------------+----------- 
id  | character varying | not null 
extension | character varying | not null 
Indexes: 
    "delete_from_me_pkey" PRIMARY KEY, btree (id) 

tab-quarantine=> \d constraining_table 
    Table "public.constraining_table" 
Column |  Type  | Modifiers 
--------+-------------------+----------- 
image | character varying | not null 
type | character varying | not null 
Foreign-key constraints: 
    "constraining_table_image_fkey" FOREIGN KEY (image) REFERENCES delete_from_me(id) 
     ON UPDATE CASCADE 
     ON DELETE RESTRICT DEFERRABLE 

यहाँ कुछ नमूना डेटा मैं बस वहाँ में blatted है::

यहाँ दो तालिकाओं का विवरण दिया जा

BEGIN; 
\set ON_ERROR_STOP 1 
SET CONSTRAINTS ALL DEFERRED; 
DELETE FROM delete_from_me WHERE id IN (
    SELECT image FROM constraining_table WHERE type = 'select_me' 
); 
DELETE FROM constraining_table WHERE type = 'select_me'; 
COMMIT; 

यह:

tab-quarantine=> SELECT * FROM delete_from_me; 
    id  | extension 
------------+----------- 
12345abcde | png 
(1 row) 

tab-quarantine=> SELECT * FROM constraining_table; 
    image | type 
------------+---------- 
12345abcde | select_me 
(1 row) 

और यहाँ मेरे लेनदेन चला जाता है लेनदेन विफल रहता है। जब मैं के माध्यम से कदम है और इस मैन्युअल रूप से करना, मैं निम्न त्रुटि संदेश के साथ प्रस्तुत कर रहा हूँ:

ERROR: update or delete on table "delete_from_me" violates foreign key constraint "constraining_table_image_fkey" on table "constraining_table" 
DETAIL: Key (id)=(12345abcde) is still referenced from table "constraining_table". 

यह एक अस्थायी तालिका लिए एक अच्छे उम्मीदवार की तरह लगता है, फिर भी मैं चाहता हूँ पता करने के लिए क्यों यह है कि है लेनदेन के अंत तक बाधाओं को प्रभावी नहीं होने के कारण मैं इस आदेश में हटा नहीं सकता हूं?

उत्तर

6

ON DELETE RESTRICT DEFERRABLE के बजाय ON DELETE NO ACTION DEFERRABLE का उपयोग करें। NO ACTION के बजाय RESTRICT का उपयोग करना बाध्यता को गैर-स्थगित करने के लिए मजबूर करता है, भले ही आप DEFERRABLE संशोधक लागू करते हैं या नहीं। भले ही बाधा deferrable घोषित किया जाता है

Referential कार्यों से कोई कार्रवाई नहीं की जाँच टाल नहीं किया जा सकता अन्य,:

यह manual page for CREATE TABLE की बारीक अक्षरों में है।

जाहिर है, उपरोक्त चेतावनी में RESTRICT शामिल है।

कोई कार्रवाई नहीं की

यह दर्शाता है कि विलोपन या अद्यतन एक विदेशी कुंजी बाधा उल्लंघन बनाना होगा एक त्रुटि का उत्पादन:

के बाद शीघ्र ही इस वाक्य NO ACTION और RESTRICT की परिभाषाएं दी गई हैं के बाद। यदि बाधा स्थगित हो जाती है, तो यह त्रुटि बाधा जांच समय पर उत्पादित की जाएगी यदि अभी भी कोई संदर्भ पंक्तियां मौजूद हैं। यह डिफ़ॉल्ट कार्रवाई है।

सीमित

यह दर्शाता है कि विलोपन या अद्यतन एक विदेशी कुंजी बाधा उल्लंघन बनाना होगा एक त्रुटि का निर्माण करें। यह कोई कार्रवाई के समान नहीं है सिवाय इसके कि चेक डिफ्रैबल नहीं है।

आप देख सकते हैं, NO ACTION, RESTRICT के समान व्यवहार करेंगे छोड़कर NO ACTION deferrable है। यही कारण है कि मैंने इसकी सिफारिश की - मुझे लगता है कि यह वही है जो आप पूछ रहे हैं।

संबंधित मुद्दे