2010-02-11 13 views
11

Bonjour, j'ai de la difficulté avec cette procédure stockée. Je reçois l'erreur: Le résultat comprend plus d'une ligne.Le résultat comportait plus d'une ligne. Erreur 1172 mysql

Voici ma procédure stockée:

DELIMITER $$ 

DROP PROCEDURE IF EXISTS `dss`.`COSTRET` $$ 
CREATE DEFINER=`dwadmin`@`192.168.%.%` PROCEDURE `COSTRET`(TDATE DATE) 
BEGIN 
    DECLARE done INT DEFAULT 0; 
    DECLARE ls_id VARCHAR(8); 
    DECLARE ld_cost DECIMAL(10,4); 
     DECLARE ld_retail DECIMAL(10,4); 
    DECLARE cur1 CURSOR FOR SELECT DISTINCT `id` FROM `prod_performance` WHERE `psc_week` = TDATE; 
    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; 

    -- Get the Cost 
    CREATE TEMPORARY TABLE IF NOT EXISTS `prod_itemcost` 
    SELECT DISTINCTROW `itemcode` ID, `mlist` COST 
    FROM (SELECT `itemcode`, `pceffdate`, `mlist` 
     FROM `purchcost` a 
     where `pceffdate` = (SELECT MAX(z.`pceffdate`) FROM `purchcost` z WHERE z.`itemcode` = a.`itemcode` 
     AND z.`pceffdate` <= TDATE)) tb 
    ORDER BY `itemcode`; 

    OPEN cur1; 
    REPEAT 
     FETCH cur1 INTO ls_id; 
     IF NOT done THEN 
      SELECT DISTINCTROW `cost` INTO ld_cost FROM `prod_itemcost` WHERE id = ls_id; 

     UPDATE LOW_PRIORITY `prod_performance` SET `current_cost` = ld_cost WHERE `psc_week` = TDATE and `id` = ls_id; 
     END IF; 
    UNTIL done END REPEAT; 
    CLOSE cur1; 

    -- Destroy Temporary Tables 
    DROP TEMPORARY TABLES IF EXISTS `prod_itemcost`; 
END $$ 

DELIMITER ; 

Toutes les solutions et recommandations sont très appréciées!

+0

Jetez un oeil à ma réponse à cette question [Erreur MySQL 1172 - Résultat composé de plus d'une ligne] [1] Merci. [1]: http://stackoverflow.com/questions/9507993/mysql-error-1172-result-consisted-of-more-than-one-row –

Répondre

1

Cette ligne

SELECT MAX(z.`pceffdate`) FROM `purchcost` z WHERE z.`itemcode` = a.`itemcode` 
    AND z.`pceffdate` <= TDATE 

a obtenu d'être le problème. Il doit retourner plus d'une rangée. Ainsi, le SGBD essaie de définir plusieurs valeurs à la même chose, ce qui bien sûr ne peut pas être fait.

Avez-vous besoin d'autre chose dans votre clause WHERE?

6

Je dirais que le problème est ici:

SELECT DISTINCTROW `cost` INTO ld_cost FROM `prod_itemcost` WHERE id = ls_id; 

et causé par ce retour plus d'une ligne. Comment vous le résoudre dépend de vos besoins. L'existence de plusieurs lignes implique-t-elle que la base de données nécessite un nettoyage, par exemple? Ou devriez-vous prendre la première valeur de «coût», ou peut-être la somme de tous les «coûts» pour id = ls_id?

Edit:

Votre clause INTO tente d'écrire plusieurs lignes à une seule variable. En regardant votre SQL, je dirais que le problème sous-jacent est que votre requête initiale de retirer seulement le dernier coût pour chaque ID est paralysé par des doublons de pceffdate. Si tel est le cas, ce SQL:

SELECT DISTINCTROW `itemcode` ID, `mlist` COST 
    FROM (SELECT `itemcode`, `pceffdate`, `mlist` 
     FROM `purchcost` a 
     where `pceffdate` = (SELECT MAX(z.`pceffdate`) FROM `purchcost` z WHERE z.`itemcode` = a.`itemcode` 
     AND z.`pceffdate` <= TDATE)) tb 

renverra plus de lignes que ceci:

SELECT DISTINCTROW `itemcode` ID 
    FROM (SELECT `itemcode`, `pceffdate`, `mlist` 
     FROM `purchcost` a 
     where `pceffdate` = (SELECT MAX(z.`pceffdate`) FROM `purchcost` z WHERE z.`itemcode` = a.`itemcode` 
     AND z.`pceffdate` <= TDATE)) tb 
+0

il a déjà un DISTINCTROW donc il ne retournera que 1 droite? pouvez-vous recommander une solution de contournement? – ryn6

+0

Ce n'est pas ce que DISTINCTROW fait (ce qui est d'ailleurs synonyme de DISTINCT). Si vous avez plusieurs valeurs différentes pour le coût de chaque ID, DISTINCT/DISTINCTROW renvoie plusieurs lignes. DISTINCT/DISTINCTROW signifie simplement que vous n'aurez pas de lignes en double. Ainsi, par exemple, si vous avez 3 lignes avec des valeurs de 50, 50 et 100, DISTINCT/DISTINCTROW retournera 2 lignes (une avec 50 et une de 100). – MartW

+0

umm donc je devrais enlever le DISTINCTROW de cette ligne? . J'ai supprimé la chose DISTINCTROW sur mon écran de sélection et il donne toujours la même erreur – ryn6

1

Le problème est que

SELECT DISTINCTROW `itemcode` ID, `mlist` COST 

pourrait stocker plusieurs coûts contre chaque ID, et ainsi

SELECT DISTINCTROW `cost` INTO ld_cost FROM `prod_itemcost` WHERE id = ls_id; 

pourrait renvoyer plusieurs lignes pour chaque identifiant.

Par exemple, si purchcost contenait les éléments suivants:

itemcode mlist pceffdate 
1   10.99 10-apr-2009 
1   11.99 10-apr-2009 
1   9.99 09-apr-2009 

prod_itemcost Ensuite table temporaire contiendrait:

itemcode mlist 
1   10.99 
1   11.99 

Ces deux étant des valeurs qui étaient en vigueur à la pceffdate la plus récente pour que itemcode . Cela causerait alors un problème avec la sélection de mlist dans ld_cost pour itemcode 1 car il y a deux valeurs correspondantes, et le scald ld_cost ne peut en contenir qu'une seule.

Vous avez vraiment besoin de regarder les données dans purchcost. S'il est possible pour un élément d'avoir plusieurs entrées avec des valeurs de liste différentes pour la même date/date/heure, vous devez décider comment cela doit être géré.Peut-être prendre la valeur la plus élevée, ou la valeur la plus basse, ou n'importe quelle valeur. Ou peut-être c'est une erreur dans les données.

+0

uhmm im un peu confus. ce dont j'ai besoin dans la table temporaire prod_itemcost, c'est d'obtenir tous les derniers prix par produit. – ryn6

0

Il existe une autre possibilité, c'est-à-dire que votre paramètre "TDATE" est identique au nom du champ de la table en majuscules ou en minuscules ou mixte. comme 'tdate', 'tDate', 'TDATE'.

alors vous devriez vérifier cela. Je frappe ça avant.