Boucler sur deux tables

XtazyMushroom Messages postés 8 Date d'inscription jeudi 7 octobre 2004 Statut Membre Dernière intervention 21 avril 2009 - 10 avril 2009 à 11:59
XtazyMushroom Messages postés 8 Date d'inscription jeudi 7 octobre 2004 Statut Membre Dernière intervention 21 avril 2009 - 21 avril 2009 à 08:54
Bonjour j'ai un petit probleme pour executer une boucle sur deux tables. Je m'explique
J'ai une table 1 et une table 2:

Table 1
id(char) valeur
334345 0
336456 0
325645 0

Et une table 2
id valeur
3256 8
336 5
33 4

Donc je voudrai recuperer la valeur id de la table 1 et la tester avec les valeurs de la table 2. Donc faire une boucle sur les 3 premiers chiffre.

Je voulais faire donc une soustraction de chaine donc enlever les x valeurs de fin pour recuperer les 4 (taille max des id de ma table 2) premiers chiffres.

Tester les 4 premiers chiffres si ils correspondent a une valeur de la table 2 affecter la variable dans la table 1, sinon decrementer et tester avec les 3 (taille max - 1) et ainsi de suite jusqu'a deux...

Mais quelques problemes avec ma boucle while!

Quelqu'un aurait une idee?

11 réponses

XtazyMushroom Messages postés 8 Date d'inscription jeudi 7 octobre 2004 Statut Membre Dernière intervention 21 avril 2009
10 avril 2009 à 12:03
Bonjour j'ai un petit probleme pour executer une boucle sur deux tables. Je m'explique J'ai une table 1 et une table 2:
Table 1
id(char) valeur
334345 0
336456 0
325645 0
Et une table 2
id valeur
3256 8
336 5
33 4

Donc je voudrai recuperer la valeur id de la table 1 et la tester avec les valeurs de la table 2. Donc faire une boucle sur les 3 premiers chiffre. Je voulais faire donc une soustraction de chaine donc enlever les x valeurs de fin pour recuperer les 4 (taille max des id de ma table 2) premiers chiffres.

Tester les 4 premiers chiffres si ils correspondent a une valeur de la table 2 affecter la variable dans la table 1, sinon decrementer et tester avec les 3 (taille max - 1) et ainsi de suite jusqu'a deux... Mais quelques problemes avec ma boucle while! Quelqu'un aurait une idee?
0
crn_c21 Messages postés 302 Date d'inscription samedi 24 janvier 2004 Statut Membre Dernière intervention 4 février 2011
10 avril 2009 à 14:21
Donne nous une idée de ce que tuas fait ce sera plus simple ainsi que le type des données de tes 2 tables
0
XtazyMushroom Messages postés 8 Date d'inscription jeudi 7 octobre 2004 Statut Membre Dernière intervention 21 avril 2009
14 avril 2009 à 08:50
Grossomodo j'ai deux tables:

Table 1:test
id(char(80)) valeur(INT)
334345 0
336456 0
325645 0

Et une table 2:prefix
id(char(80)) valeur(INT)
3256 8
336 5
33 4

Avec un curseur je veux parcourir chaque ligne de la table 1. Pour chaque ligne recuperer les 4 premiers chiffres. Ensuite si ces 4 premiers chiffre formant le nombre X est un champs de table 2 je met la valeur de X de la table 2 dans la table 1.

Pour le moment j'ai ca: Mais mon curseur passe bien de ligne en ligne mais je n'arrive pas a interpreter les valeurs des champs de la ligne de la table1. La boucle while je lai teste sur une autre table...

delimiter |
DROP PROCEDURE IF EXISTS prefixe;
CREATE PROCEDURE prefixe()
BEGIN

DECLARE num, tronc CHAR(80) DEFAULT '';
DECLARE i INT DEFAULT 4;
DECLARE done, x INT DEFAULT 0;
DECLARE CPT_ID INT;
DECLARE curs CURSOR FOR SELECT dst FROM test WHERE cout IS NULL;

DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

OPEN curs;

REPEAT
FETCH curs INTO CPT_ID;
IF NOT done THEN
ins_while:WHILE i > 2 DO

SET tronc (SELECT LEFT(CPT_ID,i)); -- ICI EST MON ERREUR CPT_ID reference mais pas valeur du champs...

SELECT count(*) INTO x
FROM prefixe WHERE dst LIKE tronc; -- DONC NE RENTRE JAMAIS LA :(

IF (x = 0) THEN
SET i = i - 1;
ELSE
UPDATE test SET cout=7777 WHERE dst=num;
LEAVE ins_while;
END IF;

END WHILE;
END IF;
UNTIL done END REPEAT;

CLOSE curs;
END|

Si quelqu'un a une idee SVP
0
XtazyMushroom Messages postés 8 Date d'inscription jeudi 7 octobre 2004 Statut Membre Dernière intervention 21 avril 2009
14 avril 2009 à 09:06
Ah oui et j'ai deja teste le DECLARE CPT_ID CHAR(80)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
XtazyMushroom Messages postés 8 Date d'inscription jeudi 7 octobre 2004 Statut Membre Dernière intervention 21 avril 2009
14 avril 2009 à 09:58
indete excusez moi:

delimiter |
DROP PROCEDURE IF EXISTS prefixe;
CREATE PROCEDURE prefixe()
BEGIN

DECLARE num, tronc CHAR(80) DEFAULT '';
DECLARE i INT DEFAULT 9;
DECLARE done, x INT DEFAULT 0;
DECLARE CPT_ID INT;
DECLARE curs CURSOR FOR SELECT dst FROM test;

DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

OPEN curs;

REPEAT
FETCH curs INTO CPT_ID;
IF NOT done THEN
ins_while:WHILE i > 2 DO
SET tronc = (SELECT LEFT(CPT_ID,i));
INSERT INTO test (dst, cout) VALUES (dst,i);

SELECT count(*) INTO x
FROM prefixe WHERE dst LIKE tronc;

IF (x = 0) THEN
SET i = i - 1;
ELSE
UPDATE test SET cout=7777 WHERE dst=num;
LEAVE ins_while;
END IF;

END WHILE;
END IF;
UNTIL done END REPEAT;

CLOSE curs;
END|
0
aieeeuuuuu Messages postés 698 Date d'inscription jeudi 16 janvier 2003 Statut Membre Dernière intervention 20 mai 2011 3
14 avril 2009 à 09:59
bonjour

pourquoi ne pas faire ça juste en une requête, plutôt que de passer par un curseur ?

UPDATE Table1 T1
SET Valeur = COALESCE(
    SELECT Valeur From Table2 WHERE T2 WHERE T2.id = (LEFT(T1.id, 4),
    SELECT Valeur From Table2 WHERE T2 WHERE T2.id = (LEFT(T1.id, 3),

    SELECT Valeur From Table2 WHERE T2 WHERE T2.id = (LEFT(T1.id, 2),
    T1.Valeur
)
0
XtazyMushroom Messages postés 8 Date d'inscription jeudi 7 octobre 2004 Statut Membre Dernière intervention 21 avril 2009
14 avril 2009 à 10:04
Par exemple:
Si on a 00336 on a un prefixe valide donc on a un prix par appel (un cout)
Si on a un 0033 c'est un prix inferieur

Si je fais cette requete il va d'abord appliquer un cout pour 00336 puis appliquer un cout pour 0033
0
aieeeuuuuu Messages postés 698 Date d'inscription jeudi 16 janvier 2003 Statut Membre Dernière intervention 20 mai 2011 3
14 avril 2009 à 12:02
Re,

non, avec ma méthode il ne devrait pas faire ca, ou alors je me suis trompé.

il devrait prendre le premiere resultat non NULL trouvé (fonction coalesce)

as-tu essayé ?
0
XtazyMushroom Messages postés 8 Date d'inscription jeudi 7 octobre 2004 Statut Membre Dernière intervention 21 avril 2009
14 avril 2009 à 12:25
Ok merci j'ai teste avec ca:
CREATE TABLE test (
dst varchar(80) NOT NULL default '',
duration int(11) NOT NULL default '0',
cout int(11) NULL);

INSERT INTO test (dst, duration) VALUES ('0033668711311', 12);
INSERT INTO test (dst, duration) VALUES ('0033666724269', 32);
INSERT INTO test (dst, duration, cout) VALUES ('0033666724269', 32, 5);
INSERT INTO test (dst, duration) VALUES ('0033466724269', 32);

-----------------

CREATE TABLE prefixe (
dst varchar(80) NOT NULL default '',
cout int(11) NOT NULL default '0');

INSERT INTO prefixe (dst, cout) VALUES ('00336', 10);
INSERT INTO prefixe (dst, cout) VALUES ('0033', 5);

------------------

qui me donne ca

+---------------+----------+------+
| dst | duration | cout |
+---------------+----------+------+
| 0033668711311 | 12 | NULL |
| 0033666724269 | 32 | NULL |
| 0033666724269 | 32 | 5 |
| 0033466724269 | 32 | NULL |
+---------------+----------+------+

et

+-------+------+
| dst | cout |
+-------+------+
| 00336 | 10 |
| 0033 | 5 |
+-------+------+

-----------------

Et t'as requete:
UPDATE TABLE test
SET cout = COALESCE(
SELECT cout From prefixe WHERE prefixe.dst = (LEFT(test.dst, 4)),
SELECT cout From prefixe WHERE prefixe.dst = (LEFT(test.dst, 3)),
test.cout
)

donne ca:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'TABLE test
SET cout = COALESCE(
SELECT cout From prefixe WHERE prefixe.dst =' at line 1


:D :D :D :D

Je regarde ou est mon erreur mais un peu fatigue si jamais ca te saute aux yeux! ;)
0
aieeeuuuuu Messages postés 698 Date d'inscription jeudi 16 janvier 2003 Statut Membre Dernière intervention 20 mai 2011 3
14 avril 2009 à 13:02
re,
un peu de fatigue oui...
tu es dans la catégorie MS SQL Server, alors qu'apaprement, vu ton message d'erreur, tu es sous MySQL :)

c'est donc je pense la fonction COALESCE qu'il ne comerpnd pas, il faut trouver l'equivalent en MySQL
pour info, COALESCE prend un nombre indéfini de parametre, et te renvoi le premier NON NULL. il doit bien y avoir un equivalent dans MySQL
0
XtazyMushroom Messages postés 8 Date d'inscription jeudi 7 octobre 2004 Statut Membre Dernière intervention 21 avril 2009
21 avril 2009 à 08:54
hehe right! Bon merci beaucoup, la fonction COALESCE existe en MySQL et ca m'a permis de faire mon update sans utiliser les curseurs! Bien vu ;)

La fonction COALESCE pour MySQL:
http://dev.mysql.com/doc/refman/5.0/fr/comparison-operators.html

Merci encore see you!
0
Rejoignez-nous