[résolu tout seul] Udate avec jointure... J'ai un trou

Udate avec jointure... J'ai un trou [résolu tout seul] - SQL/NoSQL - Programmation

Marsh Posté le 02-01-2006 à 16:06:06    

SGBD : Oracle 8.1.7
 
Problème :
J'ai une table "evp", et je veux recopier les valeurs de certaines lignes à la place des valeurs d'autres lignes.
 
J'ai donc besoin de faire une jointure sur elle-même à la sélection, afin de retrouver les valeurs à écrire (et aussi lesquelles mettre à jour)
 
C'est pas clair :D
 
Voici la requête de selection :

Code :
  1. select favp.typeve, favp.numeve, favp.codpro, favp.prxbrt, favp.prxvdu, favp.prxrev, livp.typeve, livp.numeve, livp.codpro, livp.prxbrt, livp.prxvdu, livp.prxrev
  2. from evp livp, evp favp
  3. where favp.codsoc = 2
  4. and favp.achvte = 'V'
  5. and favp.typeve = 'FAV'
  6. and favp.numeve in (812309, 812367)
  7. and livp.codsoc = favp.codsoc
  8. and livp.achvte = favp.achvto
  9. and livp.typeve = favp.typevo
  10. and livp.numeve = favp.numevo
  11. and livp.numpos = favp.numpoo
  12. and (livp.prxvdu != favp.prxvdu or livp.prxfrc != ' ')


=> Le but du jeu, c'est de recopier favp.prxbrt, favp.prxvdu et favp.prxrev à la place de livp.prxbrt, livp.prxvdu et livp.prxrev
 
Je me souviens que j'ai déjà eu ce truc à faire et que j'avais passé un temps fou à trouver la syntaxe Oracle pour faire ça, mais là je ne me souviens plus :/
 
QQ1 à ça sous la main ?


Message édité par Arjuna le 02-01-2006 à 17:02:20
Reply

Marsh Posté le 02-01-2006 à 16:06:06   

Reply

Marsh Posté le 02-01-2006 à 16:12:58    

Jeu de test :
 

Code :
  1. create table test1 (id number, val1 varchar(10), val2 varchar(1));
  2. insert into test1 (id, val1, val2) values (1, 'toto', 'O');
  3. insert into test1 (id, val1, val2) values (2, 'titi', 'O');
  4. insert into test1 (id, val1, val2) values (1, 'truc', 'N');
  5. insert into test1 (id, val1, val2) values (2, 'tata', 'O');
  6. insert into test1 (id, val1, val2) values (3, 'tutu', 'O');


 
Test 1 :

Code :
  1. update test1 a
  2. set a.val1 = b.val1
  3. from test1 b
  4. where a.id = b.id
  5. and a.val2 = 'O'
  6. and b.val2 = 'N'


 
Test 2 :

Code :
  1. update test1 a, test1 b
  2. set a.val1 = b.val1
  3. where a.id = b.id
  4. and a.val2 = 'O'
  5. and b.val2 = 'N'


 
Marche pas non plus.
 
Pourtant, je sais qu'il y a moyen de faire marcher ce truc :/

Reply

Marsh Posté le 02-01-2006 à 16:22:39    

Hmmm...
 
Avec SQL Server 2000, j'ai réussi à la faire (parceque je me souvenais de la syntaxe) sauf que je me suis rendu compte que ça ne marche pas si on boucle la jointure sur elle-même :sweat:
 

Code :
  1. from test2 b
  2. drop table test1
  3. go
  4. drop table test2
  5. go
  6. create table test1 (id numeric, val1 varchar(10), val2 varchar(1))
  7. go
  8. insert into test1 (id, val1, val2) values (1, 'toto', 'O')
  9. insert into test1 (id, val1, val2) values (2, 'titi', 'O')
  10. insert into test1 (id, val1, val2) values (1, 'truc', 'N')
  11. insert into test1 (id, val1, val2) values (2, 'tata', 'N')
  12. insert into test1 (id, val1, val2) values (3, 'tutu', 'O')
  13. go
  14. create table test2 (id numeric, val1 varchar(10), val2 varchar(1))
  15. go
  16. insert into test2 (id, val1, val2) values (1, 'toto', 'O')
  17. insert into test2 (id, val1, val2) values (2, 'titi', 'O')
  18. insert into test2 (id, val1, val2) values (1, 'truc', 'N')
  19. insert into test2 (id, val1, val2) values (2, 'tata', 'N')
  20. insert into test2 (id, val1, val2) values (3, 'tutu', 'O')
  21. go
  22. update test1
  23. set test1.val1 = test2.val1
  24. from test2
  25. where test1.id = test2.id
  26. and test1.val2 = 'O'
  27. and test2.val2 = 'N'
  28. go
  29. select *
  30. from test1
  31. go
  32. ID      VAL1  VAL2
  33. 1 truc O
  34. 2 tata O
  35. 1 truc N
  36. 2 tata N
  37. 3 tutu O


 
Rien à faire avec Oracle, même si je passe par deux tables... Grrrr c'est quoi cette syntaxe ? :o

Reply

Marsh Posté le 02-01-2006 à 16:24:23    

Méthode SQL Server avec une seule table (on passe par un sous-select) :

Code :
  1. drop table test1
  2. go
  3. create table test1 (id numeric, val1 varchar(10), val2 varchar(1))
  4. go
  5. insert into test1 (id, val1, val2) values (1, 'toto', 'O')
  6. insert into test1 (id, val1, val2) values (2, 'titi', 'O')
  7. insert into test1 (id, val1, val2) values (1, 'truc', 'N')
  8. insert into test1 (id, val1, val2) values (2, 'tata', 'N')
  9. insert into test1 (id, val1, val2) values (3, 'tutu', 'O')
  10. go
  11. update test1
  12. set test1.val1 = tmp.val1
  13. from (select * from test1) tmp
  14. where test1.id = tmp.id
  15. and test1.val2 = 'O'
  16. and tmp.val2 = 'N'
  17. go
  18. select *
  19. from test1

Reply

Marsh Posté le 02-01-2006 à 16:31:50    

Grrrrr, même en passant par une vue il veut pas :o

Reply

Marsh Posté le 02-01-2006 à 16:44:58    

Reply

Marsh Posté le 02-01-2006 à 16:50:25    

Rhâ :o
 
http://www.cheblogs.com/roller/com [...] om_another
 

Code :
  1. update (select t1.val1 val11, t2.val1 val12 from test1 t1, test1 t2 where t1.id = t2.id and t1.val2 = 'O' and t2.val2 = 'N')
  2. set val11 = val12


 

Citation :

ORA-01779 : Impossible modifier colonne correspondant à une table non protégée par une clé


(avec ou sans PK ça plante, c'est le sous-select qu'il ne veut pas mettre à jour :/)

Reply

Marsh Posté le 02-01-2006 à 16:53:37    

Cette solution, évidement, elle marche...
 

Code :
  1. update test1 a
  2. set val1 = (select b.val1 from test1 b where b.id = a.id and b.val2 = 'O')
  3. where a.val2 = 'N'
  4. and exists (select null from test1 b where b.id = a.id and b.val2 = 'O')


 
Sauf que dans mon cas, je veux mettre à jour 4 champs... Et la requête un un peu plus compliqué et tape dans une table de plus de 5 lignes... :sweat: S'pas gagné :(

Reply

Marsh Posté le 02-01-2006 à 16:56:27    

YES !!!!!!
 

Code :
  1. drop table test1;
  2. create table test1 (id number, val1 varchar(10), val2 varchar(1), val3 varchar(10));
  3. insert into test1 (id, val1, val2, val3) values (1, 'toto', 'O', 'TEST1');
  4. insert into test1 (id, val1, val2, val3) values (2, 'titi', 'O', 'TEST2');
  5. insert into test1 (id, val1, val2, val3) values (1, 'truc', 'N', 'TEST3');
  6. insert into test1 (id, val1, val2, val3) values (2, 'tata', 'N', 'TEST4');
  7. insert into test1 (id, val1, val2, val3) values (3, 'tutu', 'O', 'TEST5');
  8. update test1 a
  9. set (val1, val3) = (select b.val1, b.val3 from test1 b where b.id = a.id and b.val2 = 'O')
  10. where a.val2 = 'N'
  11. and exists (select null from test1 b where b.id = a.id and b.val2 = 'O');
  12. select *
  13. from test1;
  14. ID VAL1 VAL2 VAL3
  15. 1 toto O TEST1
  16. 2 titi O TEST2
  17. 1 toto N TEST1
  18. 2 titi N TEST2
  19. 3 tutu O TEST5

Reply

Marsh Posté le 02-01-2006 à 17:01:57    

Ca fait plaisir de se sentir aidé :o

Reply

Marsh Posté le 02-01-2006 à 17:01:57   

Reply

Marsh Posté le 02-01-2006 à 17:12:12    

Ze final bouquet :

Code :
  1. update evp livp
  2. set (prxbrt, prxvdu, prxfrc) = (
  3. select favp.prxbrt, favp.prxvdu, ' '
  4. from evp favp
  5. where favp.codsoc = 2
  6. and favp.achvte = 'V'
  7. and favp.typeve = 'FAV'
  8. and favp.numeve in (812309, 812367)
  9. and livp.codsoc = favp.codsoc
  10. and livp.achvte = favp.achvto
  11. and livp.typeve = favp.typevo
  12. and livp.numeve = favp.numevo
  13. and livp.numpos = favp.numpoo
  14. and (livp.prxvdu != favp.prxvdu or livp.prxfrc != ' '))
  15. where exists (select null
  16. from evp favp
  17. where favp.codsoc = 2
  18. and favp.achvte = 'V'
  19. and favp.typeve = 'FAV'
  20. and favp.numeve in (812309, 812367)
  21. and livp.codsoc = favp.codsoc
  22. and livp.achvte = favp.achvto
  23. and livp.typeve = favp.typevo
  24. and livp.numeve = favp.numevo
  25. and livp.numpos = favp.numpoo
  26. and (livp.prxvdu != favp.prxvdu or livp.prxfrc != ' '))


 
En fait, c'est pour mettre à jour les prix des produits dans des bons de livraison pour deux factures qui font plus de 500 lignes chacune. Et du coup, y'a qq1 qui a changé les deux factures à la main tout le week-end (sympa le réveillon :o) et j'ai pas osé lui demander de refaire la même correction les 30 bons de livraison qui en résultent :D

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed