[MySQL] Update multitables

Update multitables [MySQL] - SQL/NoSQL - Programmation

Marsh Posté le 26-07-2005 à 23:45:32    

Salut,
 
Je voudrais faire un "update multitable" avec MySQL.
 
D'après la doc, on peut :
 

Citation :


Starting with MySQL 4.0.4, you can also perform UPDATE operations that cover multiple tables. The table_references part lists the tables involved in the join. Its syntax is described in Section 13.2.7.1, “JOIN Syntax”. Here is an example:  

Code :
  1. UPDATE items,month SET items.price=month.price
  2. WHERE items.id=month.id;




 
Pourtant, lorsque je fais ma requête, il râle :
 

Code :
  1. update terrain t1, (select distinct idsolarsystem from terrain) solarsystem, (select distinct idsolarsystem, idplanet from terrain) planet
  2. set t1.owner = 1
  3. where (planet.idplanet = t1.idplanet and planet.idsolarsystem = t1.idsolarsystem)
  4. and  (solarsystem.idsolarsystem = planet.idsolarsystem)
  5. and (select count(*) from terrain t2 where t2.idsolarsystem = t1.idsolarsystem
  6.   and t2.idplanet = t1.idplanet and t2.owner is null and t2.xterrain between t1.xterrain - 2
  7.   and t1.xterrain + 2 and t2.yterrain between t1.yterrain - 2 and t1.yterrain + 2) = 25


 

Code :
  1. ERROR 1093 (HY000): You can't specify target table 'terrain' for update in FROM clause


 
PS: à la base, j'avais viré l'alias "T1", mais ça ne change rien.
 
PS²: Pourtant, c'est pas la présence de Terrain plusieur fois qui le gêne, cette requête bidon fonctionne :

Code :
  1. update terrain T1, terrain T2 set T1.owner = 1 where T1.xterrain = T2.xterrain and T1.yterrain = T2.yterrain and T2.idplanet = 1;

Reply

Marsh Posté le 26-07-2005 à 23:45:32   

Reply

Marsh Posté le 26-07-2005 à 23:46:46    

Qu'est-ce que c'est lent MySQL... J'aimerais bien faire un autre test pendant que j'attends une réponse (qui risque de tarder vu l'heure :/)

Reply

Marsh Posté le 26-07-2005 à 23:54:01    

ouille ouille ouille...
 
Tu à des jointure entre tes tables???
Elle est vachement confuse ta requete sql, tu nous fait un update en même temps un select, franchement c'est la mission pour comprendre quelque chose.. :)

Reply

Marsh Posté le 26-07-2005 à 23:56:01    

Ca vient pas non plus des sous-requêtes dans les jointures...

Reply

Marsh Posté le 26-07-2005 à 23:57:32    

Ben ça s'appelle une requête "complexe". Je met un propriétaire sur tous les terrains colonisables de mon jeu que je suis en train de programmer et que j'ai passé à la trappe depuis quelques temps.
C'est histoire de faire un petit bench entre MySQL et SQL Server. Et là, alors que je lui fait bouffer des trucs bizarres, ça marche pas là dessus...

Reply

Marsh Posté le 26-07-2005 à 23:57:58    

Sinon, c'est une requête relativement classique de mettre à jour des données d'une table en fonction d'autres tables.

Reply

Marsh Posté le 27-07-2005 à 00:06:47    

Rhâ...
 

Citation :


Incorrectly used table in subquery:  
 
Error 1093 (ER_UPDATE_TABLE_USED)
SQLSTATE = HY000
Message = "You can't specify target table 'x'
for update in FROM clause"
 
This error occurs in cases like this:  
 
UPDATE t1 SET column2 = (SELECT MAX(column1) FROM t1);
 
It's okay to use a subquery for assignment within an UPDATE statement, since subqueries are legal in UPDATE and DELETE statements as well as in SELECT statements. However, you cannot use the same table, in this case table t1, for both the subquery's FROM clause and the update target.  


 
Reste plus qu'à tout réécrire ma requête :/

Reply

Marsh Posté le 27-07-2005 à 00:12:21    

voui, ta du oublier des bouts .. :)

Reply

Marsh Posté le 27-07-2005 à 00:19:07    

Mouais... Pas terrible !
 

Code :
  1. create temporary table terrain2 select * from terrain;
  2. alter table terrain2 add primary key PK_Terrain2 (idSolarSystem, idPlanet, xTerrain, yTerrain);
  3. update terrain t1, (select distinct idsolarsystem from terrain) solarsystem, (select distinct idsolarsystem, idplanet from terrain) planet
  4. set t1.owner = 1
  5. where (planet.idplanet = t1.idplanet and planet.idsolarsystem = t1.idsolarsystem)
  6. and  (solarsystem.idsolarsystem = planet.idsolarsystem)
  7. and (select count(*) from terrain2 t2 where t2.idsolarsystem = t1.idsolarsystem
  8.   and t2.idplanet = t1.idplanet and t2.owner is null and t2.xterrain between t1.xterrain - 2
  9.   and t1.xterrain + 2 and t2.yterrain between t1.yterrain - 2 and t1.yterrain + 2) = 25
  10. drop table terrain2;


 
Rien trouvé de mieu :/
 
Heureusement, la création de la table temporaire est rapide !


Message édité par Arjuna le 27-07-2005 à 00:19:33
Reply

Marsh Posté le 27-07-2005 à 00:26:15    

Question stupide ... J'imagine que si tu as fait cette erreur c'est que sur SQL Server c'est autorisé, mais c'est pas un peu dangeureux de faire un select sur des données que tu updates? Ou alors le sgdb admet que les select sont fait avant et qu'apres, une fois que toutes les données sont obtenues, l'update se lance


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 27-07-2005 à 00:26:15   

Reply

Marsh Posté le 27-07-2005 à 00:58:13    

C'est pas une erreur.
 
En effet, l'update est effectif sur l'ensemble des résultats apportés par la partie "select".
C'est tout à fait normal d'ailleurs.
 
Quand tu fais :

Code :
  1. update matable set champ = champ + 1


 
C'est totalement classique, et c'est ce qu'il se passe : il évalue d'abors champ + 1, et met ensuite à jour le résultat.

Reply

Sujets relatifs:

Leave a Replay

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