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!
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
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.
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?
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.
Voici la solution correcte. Regardez ma réponse à cette question Erreur MySQL 1172 - Résultat composé de plus d'une ligne
Je vous remercie.