web-dev-qa-db-fra.com

Le résultat est constitué de plus d'une ligne. Erreur 1172 mysql

Bonjour, j'ai du mal avec cette procédure stockée. im obtenir l'erreur: Le résultat est constitué de plus d'une ligne.

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!

13
ryn6

Je dirais que le problème est ici:

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

et causé par le retour de plus d’une ligne. La façon dont vous le résolvez 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?

Modifier :

Votre clause INTO tente d'écrire plusieurs lignes dans une seule variable. En regardant votre SQL, je dirais que le problème sous-jacent est que votre requête initiale pour récupérer uniquement le dernier coût pour chaque ID est bloquée 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 cela:

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
7
MartW

Le problème est que 

SELECT DISTINCTROW `itemcode` ID, `mlist` COST

pourrait stocker plusieurs coûts pour 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

La table temporaire prod_itemcost contiendrait alors:

itemcode   mlist
1          10.99
1          11.99

Ces deux valeurs sont en vigueur sur la plus récente date de création du code d'article.

Cela poserait alors un problème avec la sélection de mlist dans ld_cost pour le code d’article 1, car il existe deux valeurs correspondantes et la scalaire ld_cost ne peut en contenir qu’une.

Vous devez vraiment consulter les données dans purchcost. S'il est possible qu'un élément ait plus d'une entrée avec différentes valeurs mlist pour la même date/heure, vous devez alors décider de la manière dont cela doit être géré. Peut-être prendre la valeur la plus élevée, ou la valeur la plus basse, ou une valeur quelconque. Ou peut-être est-ce une erreur dans les données.

1
Martin

Cette ligne 

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

doit être le problème. Il doit retourner plus d'une ligne. Le SGBD essaie donc de définir plusieurs valeurs pour la même chose, ce qui est évidemment impossible.

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

1
Matt Dawdy

Il existe une autre possibilité, à savoir que le paramètre "TDATE" soit identique au nom du champ de la table, en majuscule, en minuscule ou mixte. tels que 'tdate', 'tDate', 'TDATE'.

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

0
fanxiong

Voici la solution correcte. Regardez ma réponse à cette question Erreur MySQL 1172 - Résultat composé de plus d'une ligne

Je vous remercie.

0
Ataboy Josef