2013-01-06 5 views
41

Vorrei eliminare le righe che contengono una chiave esterna, ma quando provo qualcosa di simile:Eliminare righe con chiave esterna in PostgreSQL

DELETE FROM osoby WHERE id_osoby='1' 

ottengo questa dichiarazione:

ERROR: update or delete on table "osoby" violates foreign key constraint "kontakty_ibfk_1" on table "kontakty" DETAIL: Key (id_osoby)=(1) is still referenced from table "kontakty".

Come posso cancellare queste righe?

+1

Controlla anche questo [su elimina cascade] (http://stackoverflow.com/questions/10356484/how-to-add-on-delete-cascade-constraints);) È bene avere queste impostazioni nella tabella comunque ... Quando 'creiamo le chiavi esterne' aggiungiamo genitore e poi figlio'. Quindi quando cancelliamo 'cancella figlio e poi genitore';) – bonCodigo

risposta

42

Per automatizzare questo, si potrebbe definire il vincolo di chiave esterna con ON DELETE CASCADE.
Cito la the manual of foreign key constraints:

CASCADE specifies that when a referenced row is deleted, row(s) referencing it should be automatically deleted as well.

+4

Non abbiamo creato tabelle con ON' DELETE CASCADE'. Non posso cambiare la struttura delle tabelle. C'è un modo in cui le chiavi esterne vengono cancellate automaticamente? o dobbiamo seguire la strada suggerita da @juergen d – Varun

+1

@Varun: Se non puoi 'ALTER' la tabella per aggiungere un FK con' ON DELETE CASCADE', quindi eliminando a mano (una volta) o per trigger 'PRIMA DELETE '(ogni volta) sono le opzioni rimanenti. –

6

Ciò significa che nella tabella kontakty è presente una riga che fa riferimento alla riga in osoby che si desidera eliminare. Hai eliminato prima quella riga o imposta un'eliminazione a cascata sulla relazione tra le tabelle.

Powodzenia!

21

Non è possibile eliminare una chiave esterna se fa ancora riferimento a un'altra tabella. prima eliminare il riferimento

delete from kontakty 
where id_osoby = 1; 

DELETE FROM osoby 
WHERE id_osoby = 1; 
12

Non si dovrebbe raccomandare questo come una soluzione generale, ma per una tantum la cancellazione di righe in un database che non è in produzione o in uso attivo, si può essere in grado di disabilitare temporaneamente i trigger sulle tabelle in questione.

Nel mio caso, sono in modalità sviluppo e ho un paio di tabelle che fanno riferimento l'un l'altro tramite chiavi esterne. Quindi, cancellare il loro contenuto non è così semplice come rimuovere tutte le righe da una tabella prima dell'altra. Quindi, per me, ha funzionato bene per eliminare il loro contenuto come segue:

ALTER TABLE table1 DISABLE TRIGGER ALL; 
ALTER TABLE table2 DISABLE TRIGGER ALL; 
DELETE FROM table1; 
DELETE FROM table2; 
ALTER TABLE table1 ENABLE TRIGGER ALL; 
ALTER TABLE table2 ENABLE TRIGGER ALL; 

si dovrebbe essere in grado di aggiungere clausole WHERE, se lo desideri, naturalmente con cura per evitare di compromettere l'integrità del database.

C'è qualche buona, discussioni relative a http://www.openscope.net/2012/08/23/subverting-foreign-key-constraints-in-postgres-or-mysql/

3

E 'stato un po' che questa domanda è stato chiesto, la speranza può aiutare. Poiché non è possibile modificare o modificare la struttura DB, è possibile farlo. secondo il postgresql docs.

TRUNCATE - svuotare una tabella o un set di tabelle.

TRUNCATE [ TABLE ] [ ONLY ] name [ * ] [, ... ] 
    [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ] 

Descrizione

TRUNCATE rimuove rapidamente tutte le righe da una serie di tabelle. Ha lo stesso effetto di un DELETE non qualificato su ogni tabella, ma dal momento che non esegue la scansione delle tabelle, è più veloce. Inoltre, recupera immediatamente lo spazio su disco, piuttosto che richiedere una successiva operazione VACUUM. Questo è più utile su tavoli di grandi dimensioni.


troncare la tabella othertable e cascata eventuali tabelle che fanno riferimento othertable tramite vincoli di chiave esterna:

TRUNCATE othertable CASCADE; 

Lo stesso, ed anche ripristinare eventuali generatori sequenza associati:

TRUNCATE bigtable, fattable RESTART IDENTITY; 

Tronca e reimposta qualsiasi generatore di sequenza associato:

TRUNCATE revinfo RESTART IDENTITY CASCADE ;