2017-05-10 5 views
0

커서 선언에서 변수를 사용하는 방법이 있습니까? 예 -오라클의 커서 선언 쿼리에서 변수 사용

create or replace PROCEDURE PRD (IN_VAR IN VARCHAR2) 
IS 

    V_V1 TABLE.DATE_COL%TYPE; 

    /* Cursor decleration */ 
    CURSOR CUR_DUMMY 
    IS 
     SELECT COL1,COL2,COL3 
      FROM TABLE 
      WHERE DATE_COL BETWEEN V_V1 
        AND V_V1+1; 

BEGIN 
    FOR REC IN CUR_DUMMY 
    LOOP 

    SELECT TO_DATE(TO_CHAR(sysdate, 'DD-MON-YY') ||' '||(SELECT TO_CHAR(DAY_BEGIN,'HH24:MI:SS') FROM TABLE2),'DD-MON-YY HH24:MI:SS') INTO V_V1 from DUAL; 

-- other stuffs 
    END LOOP; 
END; 

여기서 커서는 필요한 레코드를 가져 오지 않습니다. 커서 선언 이전에 V_V1 값을 할당 할 수 있습니까? 커서 자체에서 날짜를 얻을 수 있지만 중복 쿼리가 선택됩니다. 더 좋은 방법이 있습니까?

+0

eaxmple이 작동하지 않습니다. 'V_V1' 값을 지정하기 전에 이미'select' 문장을 사용 했습니까? 따라서 V_V1을 선택하면 NULL입니다. – Tenzin

답변

1

커서를 반복하기 전에 V_V1에 값을 할당해야합니다. 누군가가 이미 이동해야했다함에 따라 또한,

create or replace PROCEDURE PRD (IN_VAR IN VARCHAR2) 
IS 

    V_V1 TABLE.DATE_COL%TYPE; 

    /* Cursor decleration */ 
    CURSOR CUR_DUMMY(V_V1 date) 
    IS 
     SELECT COL1,COL2,COL3 
      FROM TABLE 
      WHERE DATE_COL BETWEEN V_V1 
        AND V_V1+1; 

BEGIN 
    SELECT TO_DATE(TO_CHAR(sysdate, 'DD-MON-YY') ||' '||(SELECT TO_CHAR(DAY_BEGIN,'HH24:MI:SS') FROM TABLE2),'DD-MON-YY HH24:MI:SS') INTO V_V1 from DUAL; 
    FOR REC IN CUR_DUMMY(V_V1) 
    LOOP 

-- do stuffs 

    END LOOP; 
END; 
0

으로 어쩌면이 작업을 예를 들어 당신에게 아이디어를 줄 않는다, 내 댓글에 후속 :

DECLARE 
     CURSOR c1(nId IN NUMBER) IS 
       SELECT * 
       FROM  TableA 
       WHERE Id = nId; 
BEGIN 
     FOR r1 IN c1(nId => 3) LOOP 
       --Do something here 
       DBMS_OUTPUT.PUT_LINE('A'); 
     END LOOP; 
END; 
/

그래서 예에서, 먼저 V_V1를 가져 커서를 열고 그 값을 사용합니다.

1

하여 커서 정의에서 변수 (커서 c_dummy (V_V1 일))를 정의하고 CUR_DUMMY (V_V1) IN REC에 대한 커서를 호출 할 때 그것을 통과해야 변수 V_V1이 FOR 루프 외부에 있습니다. 커서가 열리면 결과 집합이 고정됩니다. 루프 내부의 V_V1을 변경해도 아무런 차이가 없습니다.

아래 코드는 수행 할 필요가없고 (단순성과 성능을 위해 피해야하는) 이중에서 선택하는 것을 배제하고 변수를 좀 더 의미있는 이름으로 지정합니다. 코드가 무엇인지에 대한 것이지만 - 귀하의 게시물에 대해 이름을 다시 지정하고 실제 코드에서이 이름을 사용하지 않기를 희망합니다.

또한 코드 목적에 대해 알지도 못했지만 포함되어 있으므로 BETWEEN the_date AND the_date +1에 원하지 않는 레코드가 포함될 수 있습니다. 나는 조금은 짐작하지만, >= the_date AND < the_date + 1은 아마도 정확한 절일 것입니다.

모범 사례 권장 사항으로, 패키지에 프로 시저를 아직 입력하지 않은 상태에서 코드의 주석을 에만 사용해야하는 이유는 코드가 인 이유입니다. 아니 무엇입니까 무엇입니까. 즉, 커서 선언의 주석은 코드의 가독성에 도움이되지 않습니다. 루프의 처리에 따라 BULK COLLECT를 사용해야합니다. BULK COLLECT는 다른 곳에서도 잘 설명되어 있습니다.

CREATE OR REPLACE PROCEDURE my_procedure (in_var IN VARCHAR2) 
IS  
    today_begin TABLE.DATE_COL%TYPE; 
    the_day_begin TABLE2.DAY_BEGIN%TYPE; 

    CURSOR todays_records(the_date DATE) 
    IS 
     SELECT COL1,COL2,COL3 
     FROM TABLE 
     WHERE DATE_COL BETWEEN the_date AND the_date + 1; 

BEGIN 

    SELECT DAY_BEGIN 
    INTO the_day_begin 
    FROM TABLE2; 

    today_begin := TO_DATE(TO_CHAR(sysdate, 'DD-MON-YY') ||' '|| TO_CHAR(the_day_begin,'HH24:MI:SS'),'DD-MON-YY HH24:MI:SS') 

    FOR rec IN todays_records(today_begin) 
    LOOP 
     -- other stuffs 
    END LOOP; 

END; 
+0

모든 제안에 감사드립니다. 예, 저는이 게시물의 이름을 다시 지정했습니다. – Maverick