Bonjour,
j'ai 3 tables : reservation -> ou il y 'a le statut(validé ou en attente), client et archiveClient.
j'ai effectué une procedure pour permettre de copier la table client dans archiveclient si le statut dans reservation passe de en attente à validé mais elle ne fonctionne pas après plusieurs jeux d'essais, quelqun peut m'aider.
Voila je rencontre un petit problème avec mon code.

Ce que je fais

Décrivez ici votre code ou ce que vous cherchez à faire
copier table client dans table archiveClient si statut dans table reservation = validé

drop procedure if exists ArchiveClient;
Delimiter //
create procedure ArchiveClient()
begin
declare finir int default 0;
declare idC, idR int;
declare st varchar(50);
declare curseurRes cursor for select idReservation, statut 
                              from reservation r, client c
                              where r.idClient = c.idClient
                              and statut = "validé";
declare continue HANDLER for not found set finir = 1;
open curseurRes;
fetch curseurRes into idR, st;
while finir != 1
  do
    insert into archiveClient select *
    from client
    where idClient = idC;
    fetch curseurRes into idR, st;
    END while;
    close curseurRes;
    END //
    Delimiter ;

Ce que je veux

que la copie marche

Ce que j'obtiens

select * from archiveClient;
Empty set (0.00 sec)

10 réponses


regisDevweb
Auteur
Réponse acceptée

enfaite finalement ça marchera puisque le curseur est une boucle donc pour les même id qu'il va enregistrez il marquera duplicate primary key mais pour les autres encore inconnue sur la table il marchera, merci de m'avoir aidé ^^

hello, bon, je connais pas cette syntaxe mais, logiquement, quand tu dis :

where idClient = idC;

à part le déclarer, quand est-ce que tu donnes une valeur à idC ?
ce ne serait pas plutôt l'idR du curseur ?

Il y a aussi le risque d'utiliser un accent dans 'validé' car on ne maitrise pas ou peu l'encodage de la procédure (utf-8 ou latin-1 ?)

@Huggy, pareil ça m'a piqué les yeux :)

re, je capte toujours pas la syntaxe :) mais en toute logique je déclarerais ton curseur comme ça :

declare curseurRes cursor for select idClient /* je sais po si c possible niveau jointure mais c tout ce que tu as besoin pour ton curseur, non ? */
                              from reservation r, client c
                              where r.idClient = c.idClient
                              and r.statut = "validé"; /* le statut n'est déclaré que dans la réservation */

là tu peux fetch ton curseur avec le fameux idC :

fetch curseurRes into idC;

et utiliser ta boucle en modifiant le retour du curseur en conséquence....
non ?
arrête moi si je dis n'impe :)

non c'est cohérent, je vais testé cette solution et je te dit si ça marche ^^
par ailleur statut est que dans reservation oui ^^"

ok ça marche avec ce code ^^:

drop procedure if exists ArchiveClient;
Delimiter //
create procedure ArchiveClient()
begin
declare finir int default 0;
declare idC, idR int;
declare curseurRes cursor for select distinct c.idClient
                              from reservation r, client c
                              where r.idClient = c.idClient
                              and statut = "validé";
declare continue HANDLER for not found set finir = 1;
open curseurRes;
fetch curseurRes into idC;
while finir != 1
  do
    insert into archiveClient select *
    from client
    where idClient = idC;
    fetch curseurRes into idC;
    END while;
    close curseurRes;
    END //
    Delimiter ;

mais j'ai un autre problème , ma table archiveClient contient tout les clients dont le statut est validé, si il y a deux clé primaire ca va afficher duplicate primary key '' il faudait pas mieux mettre un clé étrangère pour l'id du client et une clé primaire à part sur cette table? et si oui comment changer le insert?

hello,
tel que tu procèdes ta table archiveClient semble être un duplicata de ta table client.
du coup à chaque utilisation de ton curseur tu auras des erreurs puisqu'il voudra écraser des clés primaires....
tu n'as peut-être pas besoin de tout ça ?
par exemple ta table archiveClient n'aurait besoin que d'un seul champ (ou 2 si tu veux une clé) nommé 'idClient' contenant l'id du client. tu récupérerais ton client avec une simple jointure....
donc ton insert ressemblerait à ça :

insert into archiveClient (idClient) value (c.idClient) /* idClient de archiveClient n'est pas une clé primaire !! */
select c.idClient
from client c
...

c'est une idée...

il manque pas un ; après value(c.idClient) ? et sinon sa serait bien qu'il y ai aussi le nom du client non?

hello,
je répète : je ne connais pas cette syntaxe, mais je n'ai pas l'impression qu'il faille un ';' aux vues de tes différents posts.
le pb c que je ne sais pas si cette méthode d'insert (key value) fonction avec ton environnement ; si c le cas il n'y aurait aucun pb pour insérer tout (et seulement...) ce dont tu as besoin comme ça :

insert into archiveClient (idClient, name, keyX) value (c.idClient, c.name, c.valueKeyX) 
select c.idClient
from client c
...

peut-être la question que j'aurais du poser en premier :
tu développes dans quel environnement ?