2011-11-30 38 views
32

'daki bir kısıtlamayı değiştirmeye çalışmak Oracle tarafından sağlanan belgeleri kontrol ettim ve tabloyu düşürmeden bir kısıtlamayı değiştirmenin bir yolunu buldum. Sorun, anahtar kelimeyi tanıyamadığı için değiştirilememesidir.PostgreSQL

PostgreSQL için EMS SQL Yöneticisini kullanma. bir düzenle, orada (Oracle değil, PostgreSQL tarafından temin edilir) doğru el kitabına göre

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'i kullanırken neden Oracle belgelerini (ve bu soruyu 'plsql' ile etiketliyor) denetliyorsunuz? Tam hata nedir (hangi anahtar kelime tanınmıyor)? – Bruno

+0

HATA: sözdizimi hatası ya da yakınında "Değiştir" HAT 1: Alter Tablo public.public_insurer_credit KISITLAMA p DEĞİŞTİREN ... ^ (0.359 sn) – MISMajorDeveloperAnyways

+7

Postgres Oracle dokümanlar kontrol edilmesi ve daha sonra Postgres suçlayarak. Epik. –

cevap

23

:

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

I kullanılarak kısıtlaması bırakarak etrafında çalışmak mümkün ALTER tablo açıklamada mevcut kısıt:

: Burada

doğru kılavuzuna link

+0

Doğru belgelerin bağlantısı için teşekkür ederiz. DBA'mdan Oracle PL/SQL belgelerine sahip oldum. Rakamlar. – MISMajorDeveloperAnyways

+2

Oracle ve Oracle'ın PL/SQL'i tamamen farklı şeylerdir. Bunun tek nedeni, Oracle'ın PL/SQL (ve diğer Oracle uyumluluk özellikleri) desteğine sahip EnterpriseDB'nin * Gelişmiş Sunucu * 'ını kullanmanızdır. Ama o zaman size Oracle elkitabı –

+1

değil EnterpriseDB elkitabını vermeliydiler. Herkes bu cevabın neden bir niçin olduğunu açıklayabilir mi? –

52

Postgres'te kısıtlamalar için ALTER komut bulunmamaktadır. Bunu gerçekleştirmenin en kolay yolu, 'luk kısıtlamadır ve onu istenen parametrelerle yeniden ekleyin. Tabi ki kısıtlamanın herhangi bir değişikliği mevcut tablo verilerine karşı çalıştırılacaktır. sürümü 9.4 itibariyle

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

+1. –

+5

Dikkat: Doğru şekilde anlarsam DDL ifadeleri tabloda AccessExclusive kilidi alır, bu nedenle bu komutlar uzun sürerse, komutlar tamamlanana kadar siteniz durur. [Belge sayfası] (http://www.postgresql.org/docs/current/static/sql-altertable.html), bir dizinin otomatik olarak oluşturulmasından ziyade açıkça belirtilmesi de dahil olmak üzere daha fazla ayrıntıya sahiptir. –

25

, PostgreSQL yabancı anahtarlar için ALTER TABLE ... ALTER CONSTRAINT destekler.

Bu özellik "Allow constraint attributes to be altered, so the default setting of NOT DEFERRABLE can be altered to DEFERRABLE and back." olacaktır Sorunuza baktığımda (tür) aradığınızı düşünüyorum.

daha ayrıntılı bilgiler ve örnek burada bulabilirsiniz:
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 belgelerin '' Şu anda yalnızca yabancı anahtar kısıtlamaları değiştirilebileceğini 'unutmayın. –

+0

@MichaelHerrmann Cevabımda bunu zaten belirtmiştim. – mkurz

2

ALTER CONSTRAıNT'I her zaman uygun değil yabancı anahtar adı, bilerek gerektirecektir.

Burada yalnızca tablo ve sütun adlarını bilmeniz gereken yer var. Kullanımı:

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

Fonksiyon:

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; 

unutmayın: Bu fonksiyon ilk yabancı anahtarın özelliklerini kopyalamak olmaz. Sadece yabancı tablonun adını/sütun adını alır, geçerli anahtarı düşürür ve ,'un yerine yenisini ekler.

+0

Çok ilginç bir çözüm – tom10271