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

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