by 열공중 [PL/SQL] PL/PGSQL POSTGRESQL [2018.10.15 14:44:17]
안녕하세요 눈으로만 보다가 질문이 생겨서 이렇게 글을 올립니다.
CREATE OR REPLACE PROCEDURE Delivery
(
IN_mW_ID IN INTEGER,
IN_mO_CARRIER_ID IN INTEGER,
OUT_Result OUT VARCHAR(4000),
OUT_mSuccess OUT NATIVE_INTEGER
)
IS
sNativeError INTEGER;
DV_w_id INTEGER;
DV_o_carrier_id INTEGER;
DV_d_id INTEGER;
DV_c_id INTEGER;
DV_no_o_id INTEGER;
DV_o_total NUMERIC(15,2);
sBuffer VARCHAR(4000);
PROCEDURE SETERR
IS
BEGIN
sNativeError := SQLCODE;
END;
BEGIN
---------------------------------------------
-- INPUT ARGS, Initialize Variable
---------------------------------------------
DV_w_id := IN_mW_ID;
DV_o_carrier_id := IN_mO_CARRIER_ID;
<< RAMP_RETRY >>
sNativeError := 0;
sBuffer := '';
---------------------------------------------
-- GET OUTPUT
---------------------------------------------
FOR DV_d_id IN 1 .. 10
LOOP
BEGIN
SELECT no_o_id INTO DV_no_o_id
FROM new_order
WHERE no_w_id = DV_w_id AND
no_d_id = DV_d_id
ORDER BY no_o_id
FETCH 1 ;
EXCEPTION WHEN NO_DATA_FOUND THEN sBuffer := sBuffer || -1 || '|' || DV_d_id || '|';
CONTINUE;
WHEN OTHERS THEN SETERR;goto SQL_FINISH;
END;
BEGIN
DELETE FROM new_order
WHERE no_o_id = DV_no_o_id AND
no_d_id = DV_d_id AND
no_w_id = DV_w_id;
EXCEPTION WHEN OTHERS THEN SETERR;goto SQL_FINISH;
END;
BEGIN
SELECT o_c_id INTO DV_c_id
FROM orders
WHERE o_id = DV_no_o_id AND
o_d_id = DV_d_id AND
o_w_id = DV_w_id;
EXCEPTION WHEN OTHERS THEN SETERR;goto SQL_FINISH;
END;
BEGIN
UPDATE orders
SET o_carrier_id = DV_o_carrier_id
WHERE o_id = DV_no_o_id AND
o_d_id = DV_d_id AND
o_w_id = DV_w_id ;
EXCEPTION WHEN OTHERS THEN SETERR;goto SQL_FINISH;
END;
BEGIN
UPDATE order_line
SET ol_delivery_d = sysdate
WHERE ol_o_id = DV_no_o_id AND
ol_d_id = DV_d_id AND
ol_w_id = DV_w_id;
EXCEPTION WHEN OTHERS THEN SETERR;goto SQL_FINISH;
END;
BEGIN
SELECT SUM(ol_amount) INTO DV_o_total
FROM order_line
WHERE ol_o_id = DV_no_o_id AND
ol_d_id = DV_d_id AND
ol_w_id = DV_w_id;
EXCEPTION WHEN OTHERS THEN SETERR;goto SQL_FINISH;
END;
BEGIN
UPDATE customer
SET c_balance = c_balance + DV_o_total,
c_delivery_cnt = c_delivery_cnt + 1
WHERE c_id = DV_c_id AND
c_d_id = DV_d_id AND
c_w_id = DV_w_id;
EXCEPTION WHEN OTHERS THEN SETERR;goto SQL_FINISH;
END;
-------------------------------------------
-- Make Output-String
-------------------------------------------
sBuffer := sBuffer || DV_no_o_id || '|' || DV_d_id || '|';
END LOOP;
-------------------------------------------
-- Output Param
-------------------------------------------
OUT_Result := sBuffer;
OUT_mSuccess := 1;
COMMIT;
goto END_STEP;
<< SQL_FINISH >>
ROLLBACK;
IF ( (sNativeError = -14007) OR (sNativeError = -14032) )
THEN
goto RAMP_RETRY;
END IF;
OUT_mSuccess := 0;
<< END_STEP >>
NULL;
END;
/
이런 ORACLE PL/SQL문을 POSTGRES에 맞게 변경 중입니다.
현재 예외처리 부분은 해결을 했는데, 몇가지 질문이 있습니다.
1. << >> GOTO구문
위 구문에 GOTO <>, GOTO <> 가 나오는데,
BEGIN - END 블록을 순차적으로 진행하다가 중간에 GOTO_FINISH를 만나서 아래로 내려가면 바로 종료가 되는게 아닌가요?? 그럼 첫 BEGIN-END에서 종료가 되는건가요?
아니면
1. <<ramp_retery>>
2. a --------쿼리문
3. b----------쿼리문
4. c-----------쿼리문
goto <<ramp_retery>>
5. <<sql_finish>>
6. <<end_step>>
다시 1번의 <<ramp_retery>>로 돌아가는건지..?
그리고 다시 1번부터 6번까지 순차적으로 진행이 되는건가요?
2. ORACLE TO POSTGRESQL 변경 중 POSTGRES에서는 GOTO문이 없는데 이를 대체할 수 있는 방법이 어떤게 있을까요? IF - THEN 문으로 해보려고 하는데, 도저히 제 머리로는 해결이 안되네요..
가능하신분 있으실까요?
질문이 너무 많네요 고수님들 답변 기다리겠습니다.
-- goto 대신 성공여부 변수의 값을 할당하세요. -- 포스그래 문법을 몰라 개념적으로만 보세요. -- 초기값 할당 OUT_mSuccess := 1; -- 로직 수행 부분 -- IF OUT_mSuccess = 1 THEN -- 1번 로직 수행 중 오류 발생시 값 지정 OUT_mSuccess := 0; END IF; IF OUT_mSuccess = 1 THEN -- 2번 로직 수행 중 오류 발생시 값 지정 OUT_mSuccess := 0; END IF; -- 결과 실행 부분 -- IF OUT_mSuccess = 1 THEN COMMIT; ELSE ROLLBACK; END IF;