2012-01-25 23 views
5

Oracle veritabanında, adını bilmeden, sadece sütun_adı ve reference_column_name adlı yabancı bir anahtar var. Bu başarılı oldu,Oracle için kendi adını bilmeden dizin veya kısıtlama bırakın

declare 
fName varchar2(255 char); 
begin 
SELECT x.constraint_name into fName FROM all_constraints x 
JOIN all_cons_columns c ON 
c.table_name = x.table_name AND c.constraint_name = x.constraint_name 
WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME'; 
end; 

bu senaryonun çıktı "anonim blok tamamlandı" dir: Ben varsa bu yabancı anahtar damla gereken bir sql komut dosyası yazmak istiyorum, bu nedenle bu kullandığım koddur Ben damla kısmını eklediğinizde ama:

Error report: ORA-06550: line 9, column 5: PLS-00103: Encountered the symbol "ALTER" when expecting one of the following:

begin case declare exit for goto if loop mod null pragma raise return select update while with << close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe 06550. 00000 - "line %s, column %s:\n%s" *Cause: Usually a PL/SQL compilation error. *Action:

Yani herkes sorunu burada ne olduğunu bana söyleyebilir: Sonra

declare 
fName varchar2(255 char); 
begin 
SELECT x.constraint_name into fName FROM all_constraints x 
JOIN all_cons_columns c ON 
c.table_name = x.table_name AND c.constraint_name = x.constraint_name 
WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME'; 
if (fName != '') THEN 
    alter table MY_TABLE_NAME drop constraint fName; 
end if; 
end; 

Ben bu bir olsun? "Tablo değiştirebilir"

Bu seferki de fayda etmedi sonuç deyimi neden aynı hata oldu

declare 
    function getFName return varchar2 is 
    fName varchar2(255 char); 
    begin 
    SELECT x.constraint_name into fName FROM all_constraints x 
    JOIN all_cons_columns c ON 
    c.table_name = x.table_name AND c.constraint_name = x.constraint_name 
    WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME'; 

    return fName; 
    end; 
begin 
    if getFName() != '' then 
    alter table all_events drop constraint getFName(); 
    end if; 
end; 

:

alter table all_events drop constraint 
    (SELECT x.constraint_name into fName FROM all_constraints x 
    JOIN all_cons_columns c ON 
    c.table_name = x.table_name AND c.constraint_name = x.constraint_name 
    WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME'); 

Ben de bir fonksiyonu içine her şeyi koymak çalıştı

sonucu:

Error report: SQL Error: ORA-02250: missing or invalid constraint name 02250. 00000 - "missing or invalid constraint name" *Cause: The constraint name is missing or invalid. *Action: Specify a valid identifier name for the constraint name.

Bir sql sunucusu için (MS SQL) bunu yapmak çok kolay. Sadece @ ile bir değişken bildirmek ve bunu ayarlamak, sonra sadece onu kullanın. Oracle'de ne çalışmadığı hakkında hiçbir fikrim yok ...

cevap

6

Orijinal versiyonunuz genelde gayet iyi, çünkü bir PL/SQL bloğunda DDL'yi doğrudan çalıştıramazsınız; kısıt-name derleme zamanında biliniyordu bile bu durum olurdu

execute immediate 'alter table MY_TABLE_NAME drop constraint "' || fName || '"'; 

ancak fName kısıtlama olmadığı için o, senin durumunda iki kat doğrudur: ziyade, bir EXECUTE IMMEDIATE sarın zorunda -name, daha ziyade, sınırlama adını içeren bir değişken. Ayrıca

bu:

if (fName != '') THEN 

''NULL anlamına Oracle'da beri, anlamlı/geçerli değil. Bunun yerine,

IF fName IS NOT NULL THEN 

yazmalısınız.

+0

Hey bu konuda sadece ek bir soru: Ben bir sütun C1 eğer birden fazla kısıt adını alacağı teorik Bu select deyimi ile Tablo A1'in Tablo A2'nin C2'ye başvurduğu ve C1'in tablo A3'ün C3'e atıfta bulunduğu, bu yüzden C1-> C2 ve C1-> C3 için isimleri alacağım, bu yüzden soru hangi sütuna olduğumu referans ??? – radio

+0

@radio: 'all_constraints' üzerinde' '(r_owner, r_constraint_name)' etkin bir şekilde yabancı bir anahtardır; Başvurulan sütun (lar) hakkında bilgi almak için 'all_constraints' öğesine geri katılabilirsiniz. (Oracle'ın içinde, yabancı bir anahtar, * başka bir kısıtlamaya * yabancı anahtar olarak uygulanır. Bu, DBMS'nin yabancı anahtar kısıtlamalarını uygulamak için ne yapması gerektiğini düşündüğünüzde mantıklıdır.) – ruakh

+0

@radio: Bu arada, "teorik" endişeniz beni biraz endişelendiriyor, çünkü kodunuzla ilgili başka daha büyük sorunlar var - örneğin, "all_constraints" ve "all_cons_columns" işlevini "owner" kontrol etmeden kullanıyorsunuz ve "MY_COLUMN_NAME" ifadesinin yabancı anahtardaki tek sütun olduğundan emin olmuyorsunuz. Yani kodun biraz genel amaçlı değil. Bunu, başka birçok bilginin olduğu belirli bir durumda kullanmayı planladığınızı varsayıyordum, ancak herhangi bir nedenden ötürü kısıtlama ismini kaçırıyordum. Genel amaçlı bir kod gerekiyorsa, düzeltmeniz gereken çok şey var. – ruakh

2

Bu sütun için "R" Yazılan tüm kısıtlamalar damla için yapılması gerekenler:

begin 
    FOR rec IN (SELECT x.constraint_name fName FROM all_constraints x 
     JOIN all_cons_columns c ON 
     c.table_name = x.table_name AND c.constraint_name = x.constraint_name 
     WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME') 
    LOOP 
     EXECUTE IMMEDIATE 'ALTER TABLE MY_TABLE_NAME DROP CONSTRAINT "' || rec.fName || '"'; 
    END LOOP; 
end; 
İlgili konular