2011-11-30 10 views
32

में एक बाधा को संशोधित करने का प्रयास कर मैंने ओरेकल द्वारा प्रदान किए गए दस्तावेज़ों की जांच की है और तालिका को छोड़ दिए बिना बाधा को संशोधित करने का एक तरीका खोजा है। समस्या यह है कि यह संशोधित करने में त्रुटियों के रूप में है क्योंकि यह कीवर्ड को पहचान नहीं पाता है।PostgreSQL

PostgreSQL के लिए ईएमएस एसक्यूएल प्रबंधक का उपयोग करना।

Alter table public.public_insurer_credit MODIFY CONSTRAINT public_insurer_credit_fk1 
    deferrable, initially deferred; 

मैं बाधा का उपयोग कर छोड़ने के द्वारा यह आस-पास काम करने में सक्षम था:

ALTER TABLE "public"."public_insurer_credit" 
    DROP CONSTRAINT "public_insurer_credit_fk1" RESTRICT; 

ALTER TABLE "public"."public_insurer_credit" 
    ADD CONSTRAINT "public_insurer_credit_fk1" FOREIGN KEY ("branch_id", "order_id", "public_insurer_id") 
    REFERENCES "public"."order_public_insurer"("branch_id", "order_id", "public_insurer_id") 
    ON UPDATE CASCADE 
    ON DELETE NO ACTION 
    DEFERRABLE 
    INITIALLY DEFERRED; 
+9

जब आप PostgreSQL का उपयोग कर रहे हैं तो आप ओरेकल दस्तावेज़ (और इस सवाल को 'plsql' के साथ टैग क्यों कर रहे हैं)? सटीक त्रुटि क्या है (कौन सा कीवर्ड पहचाना नहीं गया है)? – Bruno

+0

त्रुटि: सिंटेक्स त्रुटि पर या निकट "संशोधित" पंक्ति 1: परिवर्तन तालिका public.public_insurer_credit बाधा पी संशोधित करें ... ^ (0.359 सेकंड) – MISMajorDeveloperAnyways

+7

Postgres के लिए Oracle डॉक्स जाँच हो रही है, और फिर Postgres पर आरोप लगा। महाकाव्य। –

उत्तर

23

सही मार्गदर्शन के अनुसार (जो PostgreSQL द्वारा आपूर्ति की है, नहीं ओरेकल द्वारा), कोई संशोधित है ALTER टेबल बयान में बाधा उपलब्ध:

:

यहां पर सही मार्गदर्शन के लिए लिंक है

+0

उचित दस्तावेज़ीकरण के लिंक के लिए धन्यवाद। मुझे हमारे डीबीए से ओरेकल पीएल/एसक्यूएल दस्तावेज के साथ आपूर्ति की गई थी। आंकड़े। – MISMajorDeveloperAnyways

+2

ओरेकल और ओरेकल के पीएल/एसक्यूएल पूरी तरह से अलग चीजें हैं। ऐसा करने का एकमात्र संभावित कारण यह है कि आप एंटरप्राइज़ डीबी * उन्नत सर्वर * का उपयोग कर रहे हैं जिसमें ओरेकल के पीएल/एसक्यूएल (और अन्य ओरेकल संगतता सुविधाओं) के लिए समर्थन है। लेकिन फिर उन्हें आपको एंटरप्राइज़ डीबी मैनुअल देना चाहिए था, न कि ओरेकल मैनुअल –

+1

क्या कोई यह समझा सकता है कि इस जवाब को डाउनवोट क्यों मिला? –

52

पोस्टग्रेज़ में बाधाओं के लिए ALTER कमांड नहीं है। इसे पूरा करने का सबसे आसान तरीका को बाधा है और वांछित पैरामीटर के साथ फिर से जोड़ें। निश्चित रूप से बाधा का कोई भी परिवर्तन वर्तमान तालिका डेटा के खिलाफ चलाया जाएगा।

BEGIN; 
ALTER TABLE t1 DROP CONSTRAINT ... 
ALTER TABLE t1 ADD CONSTRAINT ... 
COMMIT; 
+14

+1। –

+5

सावधान रहें: यदि मैं सही ढंग से समझता हूं, तो डीडीएल स्टेटमेंट तालिका पर एक एक्सेसएक्सक्लिकल लॉक लेते हैं, इसलिए यदि इन आदेशों में काफी समय लगता है, तो आपकी साइट कमांड तक पूर्ण हो जाएगी। [प्रलेखन पृष्ठ] (http://www.postgresql.org/docs/current/static/sql-altertable.html) में अधिक विवरण हैं, जिसमें एक इंडेक्स को स्वचालित रूप से जेनरेट करने के बजाए स्पष्ट रूप से निर्दिष्ट करना है। –

25

संस्करण 9.4 के रूप में, PostgreSQL विदेशी चाबी के लिए ALTER TABLE ... ALTER CONSTRAINT का समर्थन करता है।

यह विशेषताएं "Allow constraint attributes to be altered, so the default setting of NOT DEFERRABLE can be altered to DEFERRABLE and back." आपके प्रश्न को देखकर मुझे लगता है कि यह है कि आप किस प्रकार की तलाश में हैं।

की विस्तृत जानकारी और एक उदाहरण यहां पाया जा सकता:
http://www.depesz.com/2013/06/30/waiting-for-9-4-alter-table-alter-constraint-for-fks/

+2

http://www.postgresql.org/docs/9.4/static/sql-altertable.html –

+1

ध्यान दें कि 9.4 दस्तावेज़ कहते हैं 'वर्तमान में केवल विदेशी कुंजी बाधाओं को बदला जा सकता है।' –

+0

@ माइकलहेरमैन मैंने पहले ही अपने उत्तर में इसका उल्लेख किया था। – mkurz

2

ALTER बाधा विदेशी कुंजी नाम है, जो हमेशा सुविधाजनक नहीं है की यह जानकर की आवश्यकता होगी।

यहां कार्य है, जहां आपको केवल तालिका और कॉलम नामों को जानने की आवश्यकता है। उपयोग:

select replace_foreign_key('user_rates_posts', 'post_id', 'ON DELETE CASCADE'); 

फंक्शन:

CREATE OR REPLACE FUNCTION 
    replace_foreign_key(f_table VARCHAR, f_column VARCHAR, new_options VARCHAR) 
RETURNS VARCHAR 
AS $$ 
DECLARE constraint_name varchar; 
DECLARE reftable varchar; 
DECLARE refcolumn varchar; 
BEGIN 

SELECT tc.constraint_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name 
FROM 
    information_schema.table_constraints AS tc 
    JOIN information_schema.key_column_usage AS kcu 
     ON tc.constraint_name = kcu.constraint_name 
    JOIN information_schema.constraint_column_usage AS ccu 
     ON ccu.constraint_name = tc.constraint_name 
WHERE constraint_type = 'FOREIGN KEY' 
    AND tc.table_name= f_table AND kcu.column_name= f_column 
INTO constraint_name, reftable, refcolumn; 

EXECUTE 'alter table ' || f_table || ' drop constraint ' || constraint_name || 
', ADD CONSTRAINT ' || constraint_name || ' FOREIGN KEY (' || f_column || ') ' || 
' REFERENCES ' || reftable || '(' || refcolumn || ') ' || new_options || ';'; 

RETURN 'Constraint replaced: ' || constraint_name || ' (' || f_table || '.' || f_column || 
' -> ' || reftable || '.' || refcolumn || '); New options: ' || new_options; 

END; 
$$ LANGUAGE plpgsql; 

प्रति सचेत रहें: इस समारोह प्रारंभिक विदेशी कुंजी के गुण कॉपी नहीं करेंगे। यह केवल विदेशी तालिका का नाम/कॉलम नाम लेता है, वर्तमान कुंजी छोड़ देता है और को नए के साथ बदल देता है।

+0

बहुत दिलचस्प समाधान – tom10271