2011-05-24 3 views
2

J'ai une table qui stocke les arbres. Il y a un node_id et un parent_id.Quelle est la meilleure façon d'insérer un arbre d'une table à l'autre en utilisant Oracle

Quand je effectuez les opérations suivantes:

insert into table1 select * from table2 start with node_id = 1 connect by prior node_id = parent_id order by parent_id nulls first 

Je reçois cette erreur:

Error starting at line 6 in command: 
insert into table1 select * from table2 start with node_id = 1 connect by prior node_id = parent_id order by parent_id nulls first 
Error report: 
SQL Error: ORA-02291: integrity constraint (XVTEST.REGIONAL_DEFAULT_DELETE) violated - parent key not found 
02291. 00000 - "integrity constraint (%s.%s) violated - parent key not found" 
*Cause: A foreign key value has no matching primary key value. 
*Action: Delete the foreign key or add a matching primary key. 

Je comprends pourquoi je reçois cette erreur. Je me demandais juste s'il y avait un moyen de le faire sans faire une procédure pl/sql récursive. Pensées? Si ce n'est pas possible, quelqu'un a-t-il une procédure comme celle-ci que je pourrais utiliser comme échantillon?

Répondre

4

Une option est de créer les contraintes FOREIGN KEY comme DEFERRABLE, puis les mettre REPORT pour votre transaction, de sorte que l'application des clés étrangères est reporté à la COMMIT.

Notez que vous ne voulez pas effectuer tout SELECT pendant que le contenu des tables violent les contraintes. Dans certains cas, certaines instructions SELECT renverront des résultats inattendus ou incohérents. (Assurez-vous de tenir compte des instructions SELECT exécutées par les déclencheurs.)


-- to create foreign key constraints as deferrable 
ALTER TABLE my_table ADD CONSTRAINT my_table_fk1 
FOREIGN KEY (other_table_id) REFERENCES other_table (id) 
DEFERRABLE INITIALLY IMMEDIATE; 

-- defer all deferrable constraints until the next commit 
ALTER SESSION SET CONSTRAINTS=DEFERRED; 
-- or 
SET CONSTRAINTS ALL DEFERRED; 

-- dml operations may now temporarily violate constraints 
INSERT ... ; 
UPDATE ... ; 

-- you can check the constraints before the commit 
SET CONSTRAINTS ALL IMMEDIATE; 

-- all deferred constraints will be enforced at the next commit 
-- (a fk violation exception will be raised here, rather than by the DML) 
COMMIT; 

Quelques références utiles:

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:914629004506

http://download.oracle.com/docs/cd/B10500_01/server.920/a96524/c22integ.htm#4666


ADDENDA:

Cette approche applique spécifiquement à la base de données Oracle, et peut ne pas être applicable à d'autres moteurs de bases de données relationnelles.

L'avertissement contre exécution CHOISIT sur les tables tandis que les contraintes sont reportées applique uniquement à la session qui reporte les contraintes. Les autres sessions verront un état cohérent, car elles ne verront aucun changement non-validé. L'utilisation de contraintes DEFERRED est préférable à la désactivation et à la réactivation des contraintes, car la désactivation des contraintes affecterait toutes les sessions et la revalidation des contraintes peut consommer des ressources importantes (pour les grandes tables).

+0

Je ne l'avais pas entendu parler de différé ... merci! C'est exactement ce dont j'ai besoin! – testing123

Questions connexes