2010-02-11 2 views
11

안녕하세요, 저는이 저장 프로 시저에 어려움을 겪고 있습니다. 메신저에 오류가 발생했습니다 : 결과가 두 개 이상의 행으로 구성되었습니다.결과가 두 개 이상의 행으로 구성되었습니다. 오류 1172 mysql

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 ; 

모든 솔루션 및 권장 사항이 많이 감사합니다 :

여기 내 저장 프로 시저입니다!

+0

는이 질문에 대한 내 대답을 살펴보십시오 [MySQL의 오류 1172 - 결과는 둘 이상의 행으로 구성] [1] 감사합니다. [1] : http://stackoverflow.com/questions/9507993/mysql-error-1172-result-consisted-of-more-than-one-row –

답변

1

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

이 줄은 문제 가지고있다. 그것은 1 행 이상을 리턴해야합니다. 따라서 DBMS는 동일한 값으로 여러 값을 설정하려고합니다. 물론 불가능합니다.

WHERE 절에 다른 내용이 필요합니까?

6

내가 문제라고 말하고 싶지만은 여기에 있습니다 :이 반환 한 행으로

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

및 일으켰습니다. 해결 방법은 요구 사항에 따라 다릅니다. 여러 행의 존재가 데이터베이스에 어떤 정리 작업이 필요하다는 것을 의미합니까? 예를 들면? 또는 '비용'의 첫 번째 값을 가져야합니까, 아니면 id = ls_id의 모든 '비용'의 합계를 가져야합니까?

편집 :

귀하의 INTO 절은 하나의 변수에 여러 행을 작성하려고합니다. 귀하의 SQL 찾고, 기본 문제는 귀하의 초기 쿼리는 각 ID에 대한 최신 비용을 끌어 오기 pceffdate 중복하여 hamstrung중인 것을 말하고 싶지만. 이 경우는,이 ​​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 

는보다 많은 행을 반환합니다 그냥이 :

SELECT DISTINCTROW `itemcode` ID, `mlist` COST 

각 ID에 대한 여러 비용을 저장할 수

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

이미 DISTINCTROW가 있으므로 단지 1을 반환합니다. 권리? 해결 방법을 권장 할 수 있습니까? – ryn6

+0

그건 DISTINCTROW가하는 것과는 다릅니다 (우연히 DISTINCT와 동의어입니다). 각 ID의 비용에 대해 여러 값이 다른 경우 DISTINCT/DISTINCTROW는 여러 행을 반환합니다. DISTINCT/DISTINCTROW는 단순히 중복 행이 없다는 것을 의미합니다. 예를 들어 값이 50, 50 및 100 인 3 개의 행이있는 경우 DISTINCT/DISTINCTROW는 2 개의 행 (50 개 중 하나와 100 개 중 하나)을 반환합니다. – MartW

+0

음, 그래서 그 줄에서 DISTINCTROW를 제거해야합니까? . select staement에서 DISTINCTROW 것을 제거했지만 여전히 동일한 오류가 발생합니다. – ryn6

1

문제는, 따라서

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

각 id에 대해 여러 행을 반환 할 수 있습니다. purchcost가 포함 된 경우 예를 들어

, 다음

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

그런 다음 임시 테이블 prod_itemcost이 포함됩니다 :

itemcode mlist 
1   10.99 
1   11.99 

이 모두 그 itemcode에 대한 가장 최근의 pceffdate 시행에 있던 값 인 .

두 개의 일치하는 값이 있고 스칼라 ld_cost가 하나만 보유 할 수 있으므로 항목 코드 1에 대해 mlist를 ld_cost로 선택하면 문제가 발생합니다.

정말로 purchasecost의 데이터를 살펴야합니다. 1 개의 항목이 동일한 날짜/시간대에 대해 다른 mlist 값을 갖는 항목을 여러 개 가질 수있는 경우 처리 방법을 결정해야합니다.아마도 가장 높은 가치, 가장 낮은 가치 또는 모든 가치를 취하십시오. 또는 아마도 이것은 데이터의 오류입니다.

+0

음, 조금 혼란스러워. prod_itemcost 임시 테이블에서 필요한 것은 제품 당 최신 가격을 모두 얻는 것입니다. – ryn6

0

테이블 필드 이름과 동일한 "TDATE"매개 변수가 대문자 또는 소문자이거나 혼합 된 다른 가능성이 있습니다. 'tdate', 'tDate', 'TDATE'와 같은

그래서 확인해야합니다. 나는 전에 이것을 쳤다.