2017-02-10 6 views
2

학습을 위해 더미 데이터베이스를 만들었으며 테이블 중 하나에 일부 중복 된 레코드를 의도적으로 만들었습니다. 모든 경우에 복제 된 레코드 중 하나를 Latest = 'Y'로 플래그를 지정하고 다른 레코드를 'N'으로 플래그를 지정하고 모든 단일 레코드에 대해 Latest 플래그는 'Y'가됩니다.계산 된 값을 사용하여 PL SQL을 사용하여 열을 업데이트하는 방법

나는 나의 모든 레코드를 통해 갈 PLSQL을 사용하려고하지만 난 그것을 말한다 (자사가 기록을 중복 말할 것이다) 이전에 계산 된 값을 사용하려고 할 때 그 : 라인 :

ORA-06550

20, 열 17 : PLS-00201 : 그래서 내가 수정하려고

DECLARE CURSOR cur IS SELECT order_id, order_date, person_id, amount, successfull_order, country_id, latest, ROWCOUNT AS COUNTER FROM (SELECT order_id, order_date, person_id, amount, successfull_order, country_id, latest, ROW_NUMBER() OVER (PARTITION BY order_id, order_date, person_id, amount, successfull_order, country_id ORDER BY order_id, order_date, person_id, amount, successfull_order, country_id) ROWCOUNT FROM orders) orders FOR UPDATE OF orders.latest; rec cur%ROWTYPE; BEGIN FOR rec IN cur LOOP IF MOD (COUNTER, 2) = 0 THEN UPDATE orders SET latest = 'N' WHERE CURRENT OF cur; ELSE UPDATE orders SET latest = 'Y' WHERE CURRENT OF cur; END IF; END LOOP; END;

내가 PLSQL 새로운 오전 : 식별자 '카운터'여기

내가 사용하려고 문입니다 선언해야합니다 나는 여기에서 발견했다 : http://www.adp-gmbh.ch/ora/plsql/cursors/for_update.html

나는 진술에서 무엇을 바꾸어야 하는가, 아니면 다른 접근법을 사용해야합니까?

미리 답변 해주세요. Botond

+0

(rec.COUNTER, 2)' –

답변

0

ROWNUMCOUNTER으로 커서에 표시하십시오. 가져 오는 동안, 당신은 MOD (rec.COUNTER, 2)

+0

고마워,하지만 대답은 그런 식으로 새로운 문제가있어. 파티션을 통해 사용하기 때문에 업데이트하고 싶지 않습니다. 대신이 해결 방법을 사용했습니다. –

0

변수 COUNTER를 선언하고 루프에서 유지 (즉, 증가)해야합니다. 예제가 PL/SQL을 배우기위한 것일뿐입니다. 그러나 커서 루프를 사용하는 것과는 대조적으로 단일 SQL 문으로 작업하는 것이 훨씬 더 효과적이라는 것을 알아 두십시오.

+0

덕분에 내가 해결 방법을 사용하여 일부 도우미 열이있는 완전히 새로운 테이블을 만듭니다. 이렇게하면 PLSQL을 사용할 필요가 없습니다. –

0

처럼 커서 참조에서 액세스해야
문제는 COUNTER가 커서 기록 rec 아니라 PL/SQL 변수의 속성이라는 것이다. 그래서 :

IF MOD (COUNTER, 2) = 0 

은 다음과 같아야합니다 그러나

IF MOD (rec.COUNTER, 2) = 0 

, 당신은 그것이 하나의 MERGE 성명에서 수행 할 수 있습니다, PL/SQL 또는 커서를 사용할 필요가 없습니다 :

오라클 설치 :

CREATE TABLE orders (order_id, order_date, latest) AS 
SELECT 1, DATE '2017-01-01', CAST(NULL AS CHAR(1)) FROM DUAL UNION ALL 
SELECT 1, DATE '2017-01-02', NULL FROM DUAL UNION ALL 
SELECT 1, DATE '2017-01-03', NULL FROM DUAL UNION ALL 
SELECT 2, DATE '2017-01-04', NULL FROM DUAL UNION ALL 
SELECT 2, DATE '2017-01-01', NULL FROM DUAL UNION ALL 
SELECT 3, DATE '2017-01-06', NULL FROM DUAL; 

UPDATE 문 :

MERGE INTO orders dst 
USING (SELECT ROW_NUMBER() OVER (PARTITION BY order_id 
            ORDER BY order_date DESC) AS rn 
     FROM orders 
    ) src 
ON (src.ROWID = dst.ROWID) 
WHEN MATCHED THEN 
    UPDATE SET latest = CASE src.rn WHEN 1 THEN 'Y' ELSE 'N' END; 

출력 :

SELECT * FROM orders; 

ORDER_ID ORDER_DATE LATEST 
-------- ---------- ------ 
     1 2017-01-01 N 
     1 2017-01-02 N 
     1 2017-01-03 Y 
     2 2017-01-04 Y 
     2 2017-01-01 N 
     3 2017-01-06 Y 
당신이 MOD '와 같은 커서 참조에서 액세스해야
관련 문제