프로시저 관련 질문(컴파일, select 2번 사용) 0 2 2,265

by 비타민 [Oracle 기초] [2014.12.04 15:30:31]


프로시저를 호출해서 사용만 하다가 작성하다 보니 문의점이 있어 몇가지 질문 드립니다.

 

1. 프로시저 문 수정시에 보통 ALTER PROCEDURE문을 사용하라고 되어있던데,

수정 후 재 컴파일을 해서 사용하는 것은 기존의 프로시저(수정 전) 문을 다시 컴파일 하는 개념인가요?

- 이전에는 drop후 다시 생성해서 사용했었음. 수정시에 ALTER가 아닌 컴파일로는 불가능한지 궁금합니다.

 

2. 프로시저에서 기본 Select 한 데이터를 조건으로 Loop를 돌리는데 일부 데이터 미변경이 발생되어
미변경된 데이터를 찾아 SELECT 후 다시 변경하려고 합니다.

해당 프로시저 안에다 SELECT 후 변경하는 문(SQL문 3개)을 추가해도 문제가 없을까요?

문제가 있다면 프로시저 종료 후 따로 SQL문을 돌릴려고 합니다.

1) Select 해오는 테이블 데이터는 기본키와 MEM_ID를 기준으로 테이블 4개를 변경시킴

2) Select 한 테이블에 기본키는 1개지만 TMEMBER테이블은 이 기본키를 포함하고 있는 ID가 다수이며,
TMEMBER는 MEM_ID로 데이터를 변경하고 있어 일부 데이터 변경 누락 발생(TRR테이블 같은 문제발생)

-- ID가 대문자로도 등록이 가능하여 aaa, AAA 등 다른  ID가 동일한 기본키를 갖는 경우 발생

-- 간혹, bbb, BBB가 서로 다른 기본키로 등록되어 있는 경우도 있음

--> 2번 문제 해결을 위해 where 조건을 기본키로 주고 변경을 시키고,

     MEM_ID로 변경해야 하는 TRR테이블을 변경시키기 위해 변경된 TMEMBER의 MEM_ID를 select 후

     TRR에 where조건으로 줘서 변경을 시키려고 합니다.

     한 프로시저 내에서 Loop 종료 후 select , update, delete문을 실행시켜도 문제가 없을까요?

예시 프로시저>>

create or replace 
PROCEDURE      SHUTDOWN
                        ( code        in     varchar2
                        )
as
    iCnt   number := 0 ;
    iRowCnt   number := 0 ;
    sUser_id     VARCHAR2(10) := 'SYSTEM';
begin
   for rec in (
    SELECT F_YN
         , NO
         , MEM_ID
      , REMK
      FROM TSHUTDOWN_EXE
     WHERE GBN = code       
        )
 LOOP  
     iCnt  := iCnt + 1 ;
     iRowCnt := 0 ;

        if trim(rec.F_YN) = 'Y' then    
   UPDATE TCOM
         SET GBN = 'Y'
            ,DOWN_GBN = '1'
            ,REMK = trim(rec.REMK)
       WHERE NO = trim(rec.NO)
        ;
        else
            UPDATE TCOM
               SET GBN = 'N'
                  ,DOWN_GBN = '2'
                  ,REMK = trim(rec.REMK)
             WHERE NO = trim(rec.NO)
        ;
       end if;

  UPDATE TDETAIL
     SET STAT = '9'
        ,CAUSE = trim(rec.REMK)
        ,REG_ID = 'SYSTEM'
        ,REG_DTE = TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS')
   WHERE NO = trim(rec.NO)
     AND STAT = '4'
         ;

         UPDATE TMEMBER
            SET GBN ='1',
                CORPNO ='' , -- NO 정보
                JOIN_DTE = TO_CHAR(SYSDATE, 'YYYYMMDD'),
                REG_ID = 'SYSTEM',
                REG_DTE = TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS')
          WHERE (MEM_ID =  trim(rec.MEM_ID) -- 일부 누락됨
                 CORPNO =  trim(rec.NO)) -- 으로 교체 후 select 문 추가예정
            AND GBN = '2'
          ;
         DELETE TRR
          WHERE REF = trim(rec.MEM_ID)
          ;
         INSERT INTO TRR ( 
               ROLE_ID,
               REF,
               TYPE )
         VALUES (
               'R001',
               trim(rec.MEM_ID),
               'U' )
       ;
 END LOOP ;
  
  DELETE FROM TSHUTDOWN_EXE; 
END ;

 

by 마농 [2014.12.04 17:19:06]

1번에 대한 답은
 - 프로시져 수정은 CREATE OR REPLACE PROCEDURE 로 하면 됩니다.
2번은 뭔 얘긴지 복잡하여 이해하기 힘들지만...
 - 안된다고 될때까지 재작업 하는 방식보다는
 - 안되는 이유를 파악하고, 되게끔 만드는게 좋을 듯 하네요.


by 비타민 [2014.12.04 17:45:21]

1번에서 컴파일은 자바 컴파일과 같은 의미인가가 궁금해서 여쭈어 본 내용이었습니다.

- 기존에 만들어진 프로시저와 동일하게 create를 다시 하라는건 컴파일로 수정이 된다는 의미로 받아들이면 되는건가요?

2번이 내용이 참 복잡하긴 한데^^;

begin 에서 SELECT 한 데이터로 LOOP를 돌리고 LOOP 종료 후

이후에 SELECT를 다시 해서 써도 되는가가 문의 내용입니다.(프로시저를 많이 안 다뤄봐서^^;)

- Loop안에서 또다시 begin Loop를 돌려도 되는가가 2-1질문이었고요..

- Loop 종료 후 begin Loop를 돌려도 되는가가 2-2질문이였습니다.

아래처럼 변경해서 새로 만들긴했는데 일단 생성상에는 문제가 없고,

현재 개발 소스 수정해서 테스트 중입니다.

   begin

            LOOP

             END LOOP 후에(기존)

                  begin (추가)

                     LOOP

                     END LOOP

                    END

     END

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입