[Suppression doublons>3] ==> Ora-00913: too many values ...

==> Ora-00913: too many values ... [Suppression doublons>3] - SQL/NoSQL - Programmation

Marsh Posté le 16-04-2010 à 10:58:28    

Bonjour,
 
je suis actuellement en stage à France Télécom, et je dois traiter une table assez conséquente dans ma base de données (plusieurs millions de lignes).
Pour celà je commence par la nettoyer afin de supprimer quelques mauvaises valeurs, tels que des doublons!
 
Le problème, c'est que ces doublons ne sont pas tous en doubles  :jap: Il n'est pas rare de trouver des valeurs identiques 4,5,6, voir 700 fois dans la table..  :whistle:  
 
J'ai alors décidé de supprimer tous les doublons qui apparaissent plus de 3 fois dans ma table (donc je garde les doublons qui apparaissent 2 et 3 fois, mais ça je pense que vous aviez compris :p ).. Pour des raisons de confidentialités, le champ de la table concerné par les doublons s'appellera "ID", et la table en question s'appellera "Ma_table".
 
 
Voici la requête que j'ai faite (je suis sous Oracle10g, via Sql*Plus) :

Code :
  1. DELETE FROM Ma_table
  2. WHERE ID IN (
  3. SELECT ID,COUNT(*) FROM Ma_table GROUP BY ID HAVING COUNT(*)>3);


 
Seulement j'obtiens la réponse suivante :

Code :
  1. ORA-00913: too many values


 
Une solution à ce problème?.. Merci beaucoup de votre (future) aide  :)

Reply

Marsh Posté le 16-04-2010 à 10:58:28   

Reply

Marsh Posté le 16-04-2010 à 12:09:01    

Salut,

 

Ah les messages d'erreur à interpréter... la même requête sous Sybase te donne un "Incorrect syntax near ','" :D

 

Le souci est que le SELECT de la clause WHERE retourne DEUX champs : les id, et le count. Résultat, ta requête, quand elle est exécutée, passe par un état du genre :

 

delete from matable
where id in (1, 4 ; 2, 5)

 

Où 1 serait l'id et 4 le count(*) associé. Là, tu vois clairement qu'il y a un souci dans la syntaxe...

 

Pour que cela fonctionne, je te conseille de créer une table temporaire dans laquelle tu stockeras les ID des lignes à supprimer, et de faire ton delete via une jointure classique.

 

Au final, on comprend bien le message d'erreur : "The SQL statement requires two sets of values equal in number. This error occurs when the second set contains more items than the first set."

 

++


Message édité par Fred999 le 16-04-2010 à 12:10:04
Reply

Marsh Posté le 16-04-2010 à 13:23:50    

"Pour que cela fonctionne, je te conseille de créer une table temporaire dans laquelle tu stockeras les ID des lignes à supprimer, et de faire ton delete via une jointure classique."
 
==> C'est ce que je pensais faire au début oui :) Mais finalement d'après un autre forum il faudrait tout simplement que j'enlève mon champ "count(*)" dans la requête que j'avais faite dans mon premier message. Je dois tester tout à l'heure, si ça ne fonctionne pas alors je choisirai la méthode de la table temporaire.
Merci beaucoup  :)

Reply

Marsh Posté le 16-04-2010 à 13:52:49    

Si tu crois que tu vas effacer des millions de lignes je te conseille de mettre un top xxx dans ton select et de boucler tant que des lignes sont effacée. Sinon tu risques de finir avec des problemes de log.
La table temporaire est une bonne idée mais c'est en general utilisée pour des updates et pas des deletes (evidement tout depend de la situation).

Reply

Marsh Posté le 16-04-2010 à 13:54:42    

Oui aussi, voire de faire cela via un package, parce que si tu t'amuses à faire un begin tran sur des millions de lignes...
 
La table #tmp c'était comme ça hein, la 1e idée qui m'est venue à l'esprit, de toute manière elle ne vivra pas longtemps.

Reply

Marsh Posté le 16-04-2010 à 14:37:07    

Merci fred999, mais ça marche finalement en enlevant le "count(*)" de mon SELECT du premier post :)
Et exécution très rapide! Suppression d'environ 5000 lignes sur plusieurs millions, le tout en 2 minutes et 15 secondes!
Merci encore :)

Reply

Marsh Posté le 16-04-2010 à 14:38:01    

ps: merci aussi oliiii pour ton aide, je n'avais pas vu le message ;)

Reply

Marsh Posté le 16-04-2010 à 15:02:08    

C'est du spécifique Oracle alors, sous Sybase cette syntaxe ne fonctionne pas, fais gaffe le jour où tu seras sous un autre système :o

Reply

Sujets relatifs:

Leave a Replay

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