DB 운영 < 개발 테이블 동기화! 0 2 5,255

by 통쓰 [SQL Query] [2024.04.24 16:51:19]


안녕하세요. 

아래와 같이 동기화 테이블 건수입니다.
아래 프로시저를 개발 테이블 TRUNCATE하고 전체 INSERT SELECT로 바꾸고,
하루에 한번씩 새벽에 JOB 돌리는데 부하가 많이 갈까요?

몇 건부터 머지문으로 바꿔서 실행하는게 좋을지...감이 안잡힙니다..
많은....의견좀 부탁드립니다.




총 건수     테이블명 
--45280      BC_CUST 
--181866     BC_CUST_MAP
--26304      BC_ITEM
--27314      BC_ITEM_BAR
--400001     BC_ITEM_PLANT
--1592666    BC_ITEM_PRICE
--1592666    BC_HIER_PRICE
--71227      BC_ITEM_UNIT_CONV
--101653     BC_ITEM_PRICE_UNIT
--12121      LM_USER
--419        BC_DEPT
--242        LM_COMMON
--5764       LM_COMMON_LINE
--17576      BC_EDI_MAPPING
--198        BC_EDI_ITEM_UNIT_CONV
--124        BC_EDI_EXCEL_FORM
--139        BC_EDI_ID
--5479978    SD_CUST_CLOSE
--10015969   SD_CUST_ORDER_ITEM



CREATE OR REPLACE PROCEDURE SD_TABLE_SYNC
IS

  V_SQL          VARCHAR(500);
  V_TABLE_NM     VARCHAR(30);
  V_DB_LINK_NM   VARCHAR(30);
  V_STRT_PRIOD   VARCHAR(5);
  V_END_PRIOD    VARCHAR(5);
  V_DATE         VARCHAR(8);
  
BEGIN
    DBMS_OUTPUT.PUT_LINE('운영 테이블 -> 개발 테이블 DB 동기화');
  
    FOR TABLE_LIST IN (
        SELECT TABLE_NAME
             , DB_LINK_NAME
             , STRT_PRIOD
             , END_PRIOD
          FROM SD_INF_STD_DATE
         WHERE USE_YN = 'Y' 
      ORDER BY SORT_NO ASC
    )
        
    LOOP 
    
        -- 테이블 & DB링크 명칭 변수 매칭
        V_TABLE_NM   := TABLE_LIST.TABLE_NAME;
        V_DB_LINK_NM := TABLE_LIST.DB_LINK_NAME;
        V_STRT_PRIOD := TABLE_LIST.STRT_PRIOD;
        V_END_PRIOD  := TABLE_LIST.END_PRIOD;
        V_DATE       := 'YYYYMMDD';
        
         DBMS_OUTPUT.PUT_LINE(V_DB_LINK_NM);  
        
        -- DB링크 없을 시 리턴.
        IF V_DB_LINK_NM IS NOT NULL THEN
            -- 개발 테이블 DELETE
            V_SQL := 'DELETE FROM '|| V_TABLE_NM || V_DB_LINK_NM ||' WHERE TO_CHAR( UPDATED, '''||V_DATE||''') BETWEEN TO_CHAR( SYSDATE' || 
                      V_STRT_PRIOD ||', '''||V_DATE||''') AND TO_CHAR( SYSDATE' || V_END_PRIOD ||', '''||V_DATE||''')';        
                      
            DBMS_OUTPUT.PUT_LINE(V_TABLE_NM || V_DB_LINK_NM || ' DELETE 완료');  
            EXECUTE IMMEDIATE V_SQL;
            
            
            -- 운영테이블 -> 개발 테이블 INSERT
            V_SQL := 'INSERT INTO ' || V_TABLE_NM || V_DB_LINK_NM || ' SELECT * FROM  ' || V_TABLE_NM ||
                     ' WHERE TO_CHAR( UPDATED, '''||V_DATE||''') BETWEEN TO_CHAR( SYSDATE' || V_STRT_PRIOD ||', '''||V_DATE||''') 
                       AND TO_CHAR( SYSDATE' || V_END_PRIOD ||', '''||V_DATE||''')';        
                      
            DBMS_OUTPUT.PUT_LINE(V_TABLE_NM || V_DB_LINK_NM || ' INSERT 완료');  
            EXECUTE IMMEDIATE V_SQL;
        
        ELSE 
             DBMS_OUTPUT.PUT_LINE(V_TABLE_NM || ' 테이블의 DB링크가 없습니다.');  
        END IF;
        

     END LOOP; 
     
     COMMIT;
     DBMS_OUTPUT.PUT_LINE('운영 테이블 => 개발 테이블 DB 동기화 완료');
     
     EXCEPTION
        WHEN OTHERS THEN
        ROLLBACK;
        DBMS_OUTPUT.PUT_LINE(V_TABLE_NM || V_DB_LINK_NM || '데이터 이전중 오류가 발생하였습니다.');
     
END SD_TABLE_SYNC;

 

by 신히 [2024.04.24 20:02:04]

타겟 테이블별 키값을 최대값으로 가져오고 그 이후부터 INSERT 하는 것이 좋습니다.

프로시저는 입력값을 테이블명, 키컬럼으로 받고 테이블만큼 호출하면 되고요.

속도 증가를 위해 LOOP 시에 카운터를 넣어서 1,000 건정도마다 COMMIT을 해주세요.

조건절에서 컬럼을 TO_CHAR 하지 말고 원본 그대로 걸어주세요.


by 통쓰 [2024.04.25 10:26:17]

감사합니다! 

키값으로 받아서 삭제하고 INSERT 하는게 좋을거같아요.

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