Je migre des données d'une base de données nommée "lbc" vers une autre nommée "courta". Je souhaite transférer des données d'une table entreprise ( 1er curseur ) ainsi que ses contrats ( 2e curseur ) et devis ( 3e curseur ).
Pour ce faire j'utilise des curseurs imbriqués et des transactions.
Le transfert des 4 premières entreprises fonctionne nickel ( sur 13 entreprises ) et à la cinquième il sort de mon curseur sur les entreprises.
Y-a-t-il des règles sur l'utilisation des curseurs que je n'ai pas respecté ?
Voici mon code :
-- Procédure pour le transfert des entreprises de lbc vers courta
-- transfert de l'entité entreprise
-- table lbc.entreprise -> courta.personne
-- -> courta.contact
-- -> courta.joindre
-- transfert des contrats d'une entreprise
-- table lbc.contrat_entreprise -> courta.affaire
-- -> courta.concerne
-- transfert des devis d'une entreprise
-- table lbc.devis_entreprise -> courta.affaire
-- -> courta.concerne
-- -> courta.piece
-- -> courta.appartient
-- 06/11/17 pas d'évenements en prod pour le moment
-- transfert des evenements liés à une entreprise
-- table lbc.evenement_entreprise -> courta.evenement
-- transfert des utilisateurs gestionnaires d'une entreprise
-- table lbc.gere_entrprise -> présent dans courta.personne et courta.affaire
-- Auteur: Virginie Mouriès
-- Création: 06/11/2017
DELIMITER |
CREATE PROCEDURE transfert_entreprises()
BEGIN
-- variables pour curseur lbc.entreprise et courta.personne, courta.contact et courta.joindre
DECLARE ent_id INT;
DECLARE ent_nom VARCHAR (50);
DECLARE ent_form_soc VARCHAR(10);
DECLARE ent_capital_soc INT;
DECLARE ent_date_creation DATE;
DECLARE ent_siret VARCHAR(15);
DECLARE ent_naf CHAR(5); -- toujours vide ?
DECLARE ent_rcs VARCHAR(15); -- le même que ent_ville_rcs , utilité ?
DECLARE ent_ville_rcs VARCHAR(50);
DECLARE ent_adresse VARCHAR(50);
DECLARE ent_ville VARCHAR(50);
DECLARE ent_cp VARCHAR(10);
DECLARE ent_nom_contact, ent_prenom_contact VARCHAR(25);
DECLARE ent_tel_contact VARCHAR(20);
DECLARE ent_mail_contact VARCHAR(50);
DECLARE pers_typ_pers_id CHAR(3) DEFAULT 'SOC';
DECLARE pers_civ_id CHAR(3) DEFAULT '6'; -- 6 = Socièté
DECLARE pers_id_insert INT DEFAULT NULL;
DECLARE ctt_id_insert INT DEFAULT NULL;
-- variable pour la gestion des affaires par un utilisateur d'un cabinet
DECLARE user_id_gere INT DEFAULT 0; -- numéro da l'utilisateur dans lbc.gere_entreprise
-- Par défaut, initialisation du cabinet à 1
DECLARE cab_id INT DEFAULT 1;
-- variables pour curseur lbc.contrat_entreprise et courta.affaire
DECLARE ce_date_demande DATE;
DECLARE ce_id_type_contrat, ce_id_assurances, ce_archive INT;
DECLARE ce_no_contrat_entreprise VARCHAR(25);
DECLARE id_affaire INT;
-- variables pour curseur lbc.devis_entreprise
DECLARE devis_date_demande DATE;
DECLARE devis_id_type_contrat, devis_id_assurances_entreprise, devis_archive INT;
DECLARE devis_upload VARCHAR(50);
-- variables pour l'insertion dans courta.piece
DECLARE id_piece INT;
-- variables pour la recherche de l'assurance dans lbc.connexa puis courta.assurance
DECLARE connexa_nom VARCHAR(20); -- nom de l'assurance dans lbc.connexa
DECLARE assurance_id INT DEFAULT NULL; -- id de l'assurance dans courta.assurance
-- terminer la boucle si plus d'entreprises dans lbc.entreprise
DECLARE done_entreprise INT DEFAULT 0;
-- terminer la boucle si plus de contrat dans lbc.contrat_entreprise
DECLARE done_contrat INT DEFAULT 0;
-- terminer la boucle si plus de devis dans lbc.devis_entreprise
DECLARE done_devis INT DEFAULT 0;
DECLARE CursEntreprise CURSOR FOR
SELECT id_entreprise, nom_entreprise, forme_sociale_entreprise, capital_social_entreprise, date_creation_entreprise, siret_entreprise, naf_entreprise, rcs_entreprise, ville_rcs_entreprise, adresse_entreprise, ville_entreprise, cp_entreprise, nom_contact_entreprise, prenom_contact_entreprise, tel_contact_entreprise, mail_contact_entreprise
FROM lbc.entreprise;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done_entreprise = 1;
OPEN CursEntreprise;
entreprise_loop: LOOP
FETCH CursEntreprise INTO ent_id, ent_nom, ent_form_soc, ent_capital_soc, ent_date_creation, ent_siret, ent_naf, ent_rcs, ent_ville_rcs, ent_adresse, ent_ville, ent_cp, ent_nom_contact, ent_prenom_contact, ent_tel_contact, ent_mail_contact;
SELECT 'entreprise', ent_id, ' ', ent_nom;
SELECT 'done_entreprise ', done_entreprise;
IF done_entreprise THEN
LEAVE entreprise_loop ;
END IF;
-- Je crée une nouvelle transaction à chaque fois que j'ajoute une entreprise dans courta.personne
START TRANSACTION;
SELECT 'start transaction';
-- je cherche dans gere_entreprise quel utilisateur gère cette entreprise
-- Recherche de l'id de l'utilisateur qui gère le client dans la base lbc
SET user_id_gere = 0;
SELECT DISTINCT id_user INTO user_id_gere
FROM lbc.gere_entreprise
WHERE id_entreprise = ent_id;
SELECT 'Client gèré par ', user_id_gere;
INSERT INTO courta_dev.personne (pers_nom, typ_for_id, pers_soc_capital_social, pers_date_naissance, pers_soc_siret, pers_soc_NAF, pers_ville_naissance, pers_adresse, pers_ville, cp_auto_code, type_pers_id, civ_id, uti_id, cab_id, typ_dem_id)
VALUES (ent_nom, ent_form_soc, ent_capital_soc, ent_date_creation, ent_siret, ent_naf, ent_ville_rcs, ent_adresse, ent_ville, ent_cp, pers_typ_pers_id, pers_civ_id, user_id_gere, cab_id, 'CLI');
SET pers_id_insert = LAST_INSERT_ID();
SELECT 'entreprise cree', pers_id_insert;
-- s'il y a des informations pour le contact, je le crée
IF( ent_nom_contact IS NOT NULL OR ent_nom_contact != '') THEN
INSERT INTO courta_dev.contact (ctt_nom, ctt_prenom, ctt_tel_mobil, ctt_mail, cab_id)
VALUES (ent_nom_contact, ent_prenom_contact, ent_tel_contact, ent_mail_contact, cab_id);
SET ctt_id_insert = LAST_INSERT_ID();
SELECT 'contact cree', ctt_id_insert;
-- creation du lien personne contact
INSERT INTO courta_dev.joindre (pers_id,ctt_id)
VALUES (pers_id_insert, ctt_id_insert);
ELSE
SELECT 'pas de contact cree';
END IF;
-- Je cherche les contrats pour cette entreprise
BLOCK2: BEGIN
DECLARE CursContrat CURSOR FOR
SELECT date_demande, id_type_contrat, id_assurances, no_contrat_entreprise, archive
FROM lbc.contrat_entreprise
WHERE id_entreprise = ent_id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done_contrat = 1;
OPEN CursContrat;
contrat_loop: LOOP
FETCH CursContrat INTO ce_date_demande, ce_id_type_contrat, ce_id_assurances, ce_no_contrat_entreprise, ce_archive;
SELECT 'done_contrat ', done_contrat;
IF done_contrat THEN
-- je passe plusieurs fois dans ce curseur
SET done_contrat = 0;
LEAVE contrat_loop ;
END IF;
-- Recherche de l'id de l'assurance dans lbc
SET assurance_id = NULL; -- remise à 0
SELECT DISTINCT assurance INTO connexa_nom
FROM lbc.connexa
WHERE id_assurances = ce_id_assurances;
IF (connexa_nom = NULL) THEN
SELECT "Pas d'assurance dans connexa : id " , ce_id_assurances;
ELSE
SELECT DISTINCT ass_id INTO assurance_id
FROM courta_dev.assurance
WHERE ass_nom = connexa_nom;
END IF;
-- les affaires insérées ici proviennent de contrat_entreprise => aff_type = 'C' comme CONTRAT
-- les numéro de type contrat sont les même dans lbc et courta
INSERT INTO courta_dev.affaire (aff_type, aff_no_contrat, aff_date_devis, aff_archive, ass_id, typ_cont_id )
VALUES ('C', ce_no_contrat_entreprise, ce_date_demande, ce_archive, assurance_id, ce_id_type_contrat );
-- je récupère l'id de l'affaire que je viens de créer dans la table courta.affaire
SET id_affaire = LAST_INSERT_ID();
SELECT 'affaire cree contrat', id_affaire;
-- insertion dans la table Concerne de la relation entre Affaire et Personne
-- une Affaire pourra concerner plusieurs Personne
INSERT INTO courta_dev.concerne (pers_id,aff_id)
VALUES (pers_id_insert, id_affaire);
END LOOP contrat_loop;
CLOSE CursContrat;
END BLOCK2;
-- Je cherche les devis pour cette entreprise
BLOCK3: BEGIN
DECLARE CursDevis CURSOR FOR
SELECT date_demande_entreprise, id_type_contrat_entreprise, id_assurances_entreprise, upload_devis_entreprise, archive
FROM lbc.devis_entreprise
WHERE id_entreprise = ent_id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done_devis = 1;
OPEN CursDevis;
devis_loop: LOOP
FETCH CursDevis INTO devis_date_demande, devis_id_type_contrat, devis_id_assurances_entreprise, devis_upload, devis_archive;
SELECT 'done_devis ', done_devis;
IF done_devis THEN
-- je passe plusieurs fois dans ce curseur
SET done_devis = 0;
LEAVE devis_loop ;
END IF;
-- Recherche de l'id de l'assurance dans lbc
SET assurance_id = NULL; -- remise à 0
SELECT DISTINCT assurance INTO connexa_nom
FROM lbc.connexa
WHERE id_assurances = ce_id_assurances;
IF (connexa_nom = NULL) THEN
SELECT "Pas d'assurance dans connexa : id " , ce_id_assurances;
ELSE
SELECT DISTINCT ass_id INTO assurance_id
FROM courta_dev.assurance
WHERE ass_nom = connexa_nom;
END IF;
-- les affaires insérées ici proviennent de devis_entreprise => aff_type = 'D' comme DEVIS
-- les numéro de type contrat sont les même dans lbc et courta
INSERT INTO courta_dev.affaire (aff_type, aff_date_devis, aff_archive, ass_id, typ_cont_id )
VALUES ('D', devis_date_demande, devis_archive, assurance_id, devis_id_type_contrat);
-- je récupère l'id de l'affaire que je viens de créer dans la table courta.affaire
SET id_affaire = LAST_INSERT_ID();
SELECT 'affaire cree devis', id_affaire;
-- insertion dans la table Concerne de la relation entre Affaire et Personne
-- une Affaire pourra concerner plusieurs Personne
INSERT INTO courta_dev.concerne (pers_id,aff_id)
VALUES (pers_id_insert, id_affaire);
-- insertion dans la table Piece
INSERT INTO courta_dev.piece (pie_url,typ_pie_id, uti_id, cab_id)
VALUES (devis_upload,'DEV',user_id_gere,cab_id);
-- je récupère l'id de la piece que je viens de créer dans la table courta.piece
SET id_piece = LAST_INSERT_ID();
SELECT 'piece cree ', id_piece;
-- insertion dans la table Appartient de la relation entre Affaire et Pièce avec app_type ='A' comme lenom de la table Affaire (app_type peut valoir 'A' comme affaire lorsque la Pièce appartient à uneAffaire)
INSERT INTO courta_dev.appartient (pie_id,app_id, app_type)
VALUES (id_piece,id_affaire,'A');
END LOOP devis_loop;
CLOSE CursDevis;
END BLOCK3;
-- Je finis la transaction si l'entreprise, les contacts, les affaires , ... ont été enregistrés
COMMIT;
END LOOP entreprise_loop;
CLOSE CursEntreprise;
END|
Et l'affichage :
Résultats de l'exécution de la procédure `transfert_entreprises`
entreprise
ent_id
ent_nom
entreprise
8
Girard
done_entreprise
done_entreprise
done_entreprise
0
start transaction
start transaction
Client gèré par
user_id_gere
Client gèré par
5
entreprise cree
pers_id_insert
entreprise cree
669
contact cree
ctt_id_insert
contact cree
120
done_contrat
done_contrat
done_contrat
0
affaire cree contrat
id_affaire
affaire cree contrat
1878
done_contrat
done_contrat
done_contrat
0
affaire cree contrat
id_affaire
affaire cree contrat
1879
done_contrat
done_contrat
done_contrat
0
affaire cree contrat
id_affaire
affaire cree contrat
1880
done_contrat
done_contrat
done_contrat
0
affaire cree contrat
id_affaire
affaire cree contrat
1881
done_contrat
done_contrat
done_contrat
1
done_devis
done_devis
done_devis
1
entreprise
ent_id
ent_nom
entreprise
9
AMS Deneux
done_entreprise
done_entreprise
done_entreprise
0
start transaction
start transaction
Client gèré par
user_id_gere
Client gèré par
5
entreprise cree
pers_id_insert
entreprise cree
670
contact cree
ctt_id_insert
contact cree
121
done_contrat
done_contrat
done_contrat
0
affaire cree contrat
id_affaire
affaire cree contrat
1882
done_contrat
done_contrat
done_contrat
1
done_devis
done_devis
done_devis
0
affaire cree devis
id_affaire
affaire cree devis
1883
piece cree
id_piece
piece cree
1951
done_devis
done_devis
done_devis
1
entreprise
ent_id
ent_nom
entreprise
10
Oplus conseil
done_entreprise
done_entreprise
done_entreprise
0
start transaction
start transaction
Client gèré par
user_id_gere
Client gèré par
5
entreprise cree
pers_id_insert
entreprise cree
671
contact cree
ctt_id_insert
contact cree
122
done_contrat
done_contrat
done_contrat
0
affaire cree contrat
id_affaire
affaire cree contrat
1884
done_contrat
done_contrat
done_contrat
1
done_devis
done_devis
done_devis
1
entreprise
ent_id
ent_nom
entreprise
18
TF1
done_entreprise
done_entreprise
done_entreprise
0
start transaction
start transaction
Client gèré par
user_id_gere
Client gèré par
0
entreprise cree
pers_id_insert
entreprise cree
672
contact cree
ctt_id_insert
contact cree
123
done_contrat
done_contrat
done_contrat
0
affaire cree contrat
id_affaire
affaire cree contrat
1885
done_contrat
done_contrat
done_contrat
0
affaire cree contrat
id_affaire
affaire cree contrat
1886
done_contrat
done_contrat
done_contrat
1
done_devis
done_devis
done_devis
1
entreprise
ent_id
ent_nom
entreprise
13
Lg immo
done_entreprise
done_entreprise
done_entreprise
1
Merci de votre aide.
- Edité par VirginieMouriès 8 novembre 2017 à 9:36:35
Arf ... dans la précipitation je n'avais pas vu que done_* étaient tes variables de gestion des curseurs ... je croyais que c'était une valeur en table que tu testais ... désolé ...
Maintenant, j'ai beau relire ton code, je ne vois pas de problème ...
La requête :
SELECT id_entreprise
FROM lbc.entreprise;
Te retourne bien 13 enregistrements ? et pas seulement les id 8,9,10,18 et 13 ?
Si 13, est-ce que certains ne sont pas sauté ? On voit que tu traites 8,9,10,18,13 dans cet ordre, n'y-a-t-il pas des id que devraient être intercalés ?
Pourquoi PhpMyAdmin ne les met pas par ordre croissant ?
Est-ce que ça veut dire que l'id 18 a été "bidouillé" ?
J'ai ajouté un ORDER BY id_entreprise dans mon curseur sur les entreprises, la procédure s'arrête quand même après l'entreprise avec id 18, qui est désormais la 19.
- Edité par VirginieMouriès 8 novembre 2017 à 14:54:59
DECLARE CursEntreprise CURSOR FOR
SELECT id_entreprise, nom_entreprise, forme_sociale_entreprise, capital_social_entreprise, date_creation_entreprise, siret_entreprise, naf_entreprise, rcs_entreprise, ville_rcs_entreprise, adresse_entreprise, ville_entreprise, cp_entreprise, nom_contact_entreprise, prenom_contact_entreprise, tel_contact_entreprise, mail_contact_entreprise
FROM lbc.entreprise;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done_entreprise = 1;
BEGIN
OPEN CursEntreprise;
entreprise_loop: LOOP
FETCH CursEntreprise INTO ent_id, ent_nom, ent_form_soc, ent_capital_soc, ent_date_creation, ent_siret, ent_naf, ent_rcs, ent_ville_rcs, ent_adresse, ent_ville, ent_cp, ent_nom_contact, ent_prenom_contact, ent_tel_contact, ent_mail_contact;
IF done_entreprise THEN
LEAVE entreprise_loop ;
END IF;
...
DECLARE CursContrat CURSOR FOR
SELECT date_demande, id_type_contrat, id_assurances, no_contrat_entreprise, archive
FROM lbc.contrat_entreprise
WHERE id_entreprise = ent_id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done_contrat = 1;
BEGIN
OPEN CursContrat;
contrat_loop: LOOP
FETCH CursContrat INTO ce_date_demande, ce_id_type_contrat, ce_id_assurances, ce_no_contrat_entreprise, ce_archive;
IF done_contrat THEN
LEAVE contrat_loop ;
END IF;
...
END LOOP contrat_loop;
CLOSE CursContrat;
END;
DECLARE CursDevis CURSOR FOR
SELECT date_demande_entreprise, id_type_contrat_entreprise, id_assurances_entreprise, upload_devis_entreprise, archive
FROM lbc.devis_entreprise
WHERE id_entreprise = ent_id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done_devis = 1;
BEGIN
OPEN CursDevis;
devis_loop: LOOP
FETCH CursDevis INTO devis_date_demande, devis_id_type_contrat, devis_id_assurances_entreprise, devis_upload, devis_archive;
IF done_devis THEN
LEAVE devis_loop ;
END IF;
...
END LOOP devis_loop;
CLOSE CursDevis;
END;
END LOOP entreprise_loop;
CLOSE CursEntreprise;
END;
Avec mon niveau de connaissance je ne peux malheureusement pas t'aider plus ...
Je te tiens informé dés que je trouve la solution à mon problème.
Un grand merci pour t'être penché sur mon soucis.
Bonne journée
- Edité par VirginieMouriès 9 novembre 2017 à 10:06:58
Virgi
MySQL Curseurs imbriqués
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.