Database & NoSQL

반응형

.주기적으로 수행되어지는 JOB을 JOB QUEUE를 사용하여 스케줄링 할 수 있습니다.. 
 JOB을 스케줄링 하기 위해서 ORACLE의 DBMS_JOB 패키지를 이용합니다.. 
 JOB QUEUE PROCESS가 JOB QUEUE 안의 잡을 수행합니다.. 
 JOB으로 등록될 수 있는 것은 PL/SQL 프로시저 또는 패키지가 되며 
 예를 들어소스 디비의 테이블들에서 타겟 테이블로 데이터를 적재하는 프로시저를 생성했는데 
 1분단위로 데이터를 타겟 테이블로 적재를 해야 할 때 DBMS_JOBS에 등록하여 
 스케줄링 할 수 있습니다. 

  

.JOB_QUEUE_PROCESSES 파라미터가 이와 관련된 초기화 파라미터로 0으로 설정되면 
 JOB QUEUE PROCESS는 시작되지 않으며 JOB QUEUE의 어느 잡도 수행되지 않습니다.. 
 JOB_QUEUE_PROCESSES 파라미터의 MAX값이 설정되어야 오라클 인스턴스 위에서 
 동시에 잡을 수행할 수 있다. 설정할 수 있는 최고 값은 1000입니다.. 
 JOB_QUEUE_PROCESSES=60 과 같이 설정할 수 있습니다.. 

  

.등록되거나 수행되는 잡에 대해서는 DBA_JOBS 또는 USER_JOBS 딕셔너리 뷰를 통해 
 확인 할 수 있다. 

.JOB_QUEUE_PROCESSES 는 다이나믹 하게 DB를 SHUTDOWN하지 않고 ALTER SYSTEM 
 명령을 이용해서 설정할 수 있습니다. 
 ALTER SYSTEM SET JOB_QUEUE_PROCESSES = 20; 

  

.JOB QUEUE안의 JOB을 스케줄링 하기 위해서는 DBMS_JOBS패키지를 사용할 수 있으며 
 JOB_QUEUE를 사용하기 위해 관련된 DB 권한은 없다. 

  

.다음은 DBMS_JOBS의 패키지를 사용하기 위한 패키지의 프로시져들입니다. 
  
 SUBMIT - 잡큐의 잡을 등록합니다. 
  REMOVE - 잡큐의 잡을 제거합니다. 
  CHANGE - 잡큐의 잡을 변경합니다. 
  NEXT_DATE - 잡의 다음 수행시간을 변경합니다. 
  INTERVAL - 잡 수행 주기를 변경합니다. 
  WHAT - 잡으로 등록된 프로시저 또는 패키지를 변경합니다. 
  RUN - 잡을 수동으로 강제로 수행합니다. 


 .새 JOB을 JOB QUEUE에 등록하기 위해 사용되는 파라미터로 DBMS_JOB.SUBMIT()에 들어가느 
  파라미터 입니다. 
  
  JOB - OUTPUT 파라미터로 생성한 잡에 의해 할당되는 식별자 입니다. 
  WHAT - JOB QUEUE에 등록되는 PL/SQL 프로시저 또는 패키지 입니다. 
  NEXT_DATE - 잡이 수행되는 다음 시간입니다. 
  INTERVAL - 잡이 수행되는 주기로 초 단위까지 지정 가능합니다. 
   
  JOB_QUEUE에 등록하는 예제입니다. 
 VARIABLE jobno NUMBER 
 BEGIN 
   DBMS_JOB.SUBMIT(:jobno, 
                   'SP_IN_EMP_SAL;', 
                   SYSDATE, 
                   'SYSDATE + 1'); 
   COMMIT; 
 END; 
 / 

 위의 PL/SQL문을 SQL PLUS에서 수행합니다. 
  첫번째 파라미터가 JOB NUMBER가 부여되는 부분이고 
  두번째 파라미터가 WHAT으로 SP_IN_EMP_SAL이라는 프로시저를 등록했습니다. 
  세번째 파라미터가 NEXT_DATE이며 4번째 파라미터가 잡 수행 주기로 하루에 한번씩 
  수행하라는 의미입니다. 


  DBMS_JOB을 이용하면 특정시간, 특정요일, 특정일, 30초단위, 매분 정각, 매시정각 
  등 다양하게  잡을 스케줄링 하는 것이 가능합니다. 
  ETL 수행 할 때도 유용하게 사용할 수 있습니다. 


  

잡 수행 간격 조정의 예 
 .SYSDATE+ 7  :  7일에 한번씩 잡이 수행됩니다. 
 .SYSDATE+1/24 : 1시간에 한번씩 잡이 수행됩니다. 
 .SYSDATE+30/86400 : 30초에 한번씩 잡이 수행됩니다. 
 .최초 잡 수행시간이 14:02분일 경우 매시 14:02분에 잡을 수행해야 될 경우 
   =>trunc(SYSDATE,'MI')+1/24  
 .최조 잡 수행시간이 06시 이고 매 8시간마다 정각에 잡이 수행되어야 될 경우 
   =>trunc(SYSDATE,'MI')+8/24 
 .매주 월요일 정각 3시에 잡이 수행되어야 할 경우 
   =>NEXT_DAY(TRUNC(SYSDATE),'MONDAY')+15/25 
 .각 분기마다 첫번째 월요일에 잡이 수행되어야 될 경우 
   =>NEXT_DAY(ADD_MONTHS(TRUNC(SYSDATE,'Q'),3),'MONDAY') 

주의> dbms_job으로 잡을 스케줄링하게 될 경우 예를 들어 잡 최초 수행시간이 22일 14:00시이고 
         매시 정각에 잡이 수행되어야 할 경우 SYSDATE+1/24로 간격을 주게 되면 매 정시에 도는 것이 
         아니라 잡 수행 시간에 따라 약간씩 늦어지게 되어 14:00:04 => 15:00:07 => 16:00:10 이런식으로 
         잡 수행시간이 잡히게 됩니다. 따라서 정각에 수행되게 하려면 trunc함수를 이용해서 무조건 분에서 
         잘라내여 00으로 만들어 준다. trunc(SYSDATE,'MI') 

  

잡의 삭제 
 BEGIN 
 DBMS_JOB.REMOVE(14443); 
 END; 
 / 
 14443은 잡 번호 이다. USER_JOBS 데이터 딕셔너리 뷰를 보면 잡 번호를 알 수 있습니다. 

  

잡의 변경 
 BEGIN 
 DBMS_JOB.CHANGE(14144, NULL, NULL, 'SYSDATE + 3'); 
 END; 
 / 


잡으로 등록된 프로시저/패키지 변경 
BEGIN 
 DBMS_JOB.WHAT(14144, 
     'SP_IN_EMP_SAL;'); 
END; 



잡 다음 수행시간 변경 
BEGIN 
 DBMS_JOB.NEXT_DATE(14144, TRUNC(SYSDATE,'MI') + 4); 
END; 


  


잡 수행 간격 변경 
BEGIN 
 DBMS_JOB.INTERVAL(14144, TRUNC(SYSDATE,'MI')+30/1440); 
END; 


  


잡 수행 정지 
  잡이 BROKEN되면 잡은 수행되지 않으며 강제로 수행 할 시에는 DBMS_JOB.RUN()을 통해  수행합니다.. 
BEGIN 
 DBMS_JOB.BROKEN(14144, TRUE); 
END; 


  


잡큐 정보 VIEWING 
 DBA_JOBS, USER_JOBS, ALL_JOBS를 이용합니다. 


SELECT JOB, NEXT_DATE, NEXT_SEC, FAILURES, BROKEN 
FROM DBA_JOBS; 

JOB    NEXT_DATE  NEXT_SEC  FAILURES   B 
------- ---------  --------   --------   - 
9125    01-JUN-01   00:00:00     4       N 
14144   24-OCT-01   16:35:35    0       N 
9127    01-JUN-01   00:00:00    16       Y 
3 rows selected. 


  

DBMS_JOB의 활용예제를 주기적으로 소스테이블에서 타켓 테이블로 

적재할 시 어떻게 사용할 수 있는지 간단하게 예를 만들었습니다 

  

--수행될 잡의 목록이 들어갈 테이블 
CREATE TABLE JOB_LIST 
(JOB_ID VARCHAR2(2), 
 JOB_TYPE VARCHAR2(1), 
 JOB_NAME VARCHAR2(30), 
 JOB_EXEC_HOUR VARCHAR(2), 
 JOB_PARENTID VARCHAR2(2), 
 CONSTRAINTS JOB_LIST_PK PRIMARY KEY(JOB_ID) 
 USING INDEX 
 TABLESPACE CYS_INDEX 
 PCTFREE 0 
 STORAGE(INITIAL 32K NEXT 32K PCTINCREASE 0) 
 NOLOGGING) 
 TABLESPACE CYS_DATA 
 PCTFREE 0 
 STORAGE(INITIAL 128K NEXT 128K PCTINCREASE 0); 
 / 
  

CREATE UNIQUE INDEX JOB_LIST_IDX01 
ON JOB_LIST(JOB_NAME,JOB_EXEC_HOUR) 
TABLESPACE CYS_INDEX 
PCTFREE 0 
STORAGE(INITIAL 64K NEXT 64K PCTINCREASE 0); 



-잡 수행 히스토리 테이블로 하루에 한번씩 JOB_LIST 테이블에서 LOG테이블로 JOB_LIST가 복사된다. 
CREATE TABLE JOB_LOG 
(JOB_ID VARCHAR2(2), 
 JOB_EXEC_DATE VARCHAR2(8), 
 JOB_START_TIME DATE, 
 JOB_END_TIME DATE, 
 JOB_DATASTART_TIME DATE, 
 JOB_DATAEND_TIME DATE, 
 JOB_STATUS VARCHAR2(1), 
 JOB_ERR_MSG VARCHAR2(100), 
 CONSTRAINTS JOB_LOG_PK PRIMARY KEY(JOB_ID,JOB_EXEC_DATE) 
 USING INDEX 
 TABLESPACE CYS_INDEX 
 PCTFREE 0 
 STORAGE(INITIAL 128K NEXT 128K PCTINCREASE 0) 
 NOLOGGING, 
 CONSTRAINTS JOB_LIST_FK FOREIGN KEY(JOB_ID) 
 REFERENCES JOB_LIST(JOB_ID)) 
 TABLESPACE CYS_DATA 
 STORAGE(INITIAL 1M NEXT 1M PCTINCREASE 0) 


--JOB_ID를 부여하기 위한 시퀀스 
CREATE SEQUENCE JOB_NUM 
START WITH 1 
INCREMENT BY 1 


--하루에 한번 DBMS_JOB을 이용하여 JOB_LIST의 JOB들을 JOB_LOG에 INSERT하기 위한 프로시져 
--다음날 수행할 JOB을 LOG로 넣는다. 
CREATE OR REPLACE PROCEDURE 
SP_IN_JOB_LOG(V_INDATE IN VARCHAR2 DEFAULT NULL) 
AS 
BEGIN 
  INSERT INTO JOB_LOG 
  SELECT JOB_ID, 
    NVL(V_INDATE,TO_CHAR(SYSDATE+1,'YYYYMMDD')), 
   NULL, 
   NULL, 
   NULL, 
   NULL, 
   'N', 
   NULL 
  FROM JOB_LIST; 
  
  COMMIT; 
END SP_IN_JOB_LOG; 

  

--SP_IN_JOB_LOG 프로시저를 DBMS_JOB에 등록한다. 
DECLARE 
    JOB_NUMBER NUMBER; 
BEGIN 
  DBMS_JOB.SUBMIT(JOB_NUMBER,  --JOB번호 
        'SP_IN_JOB_LOG;',  --프로시저명 
         TO_DATE('20050208180000','YYYYMMDDHH24MISS'),  --NEXT_DATE 
        'TRUNC(SYSDATE,''MI'')+1');  --잡 수행 간격(매일 정각 6시) 
END; 


--JOB_LIST에 수행할 프로시져(JOB)을 등록 
--DBA_USERS테이블을 이용해서 24개의 로우를 만들어 낸 후 카테시안 프러덕을 이용 
INSERT INTO JOB_LIST 
SELECT JOB_NUM.NEXTVAL JOB_ID, 
    JOB_TYPE, 
    JOB_NAME, 
    B.CNT JOB_EXEC_HOUR, 
    NULL 
FROM( 
  SELECT NULL JOB_ID, 
      'F' JOB_TYPE, 
      'SP_IN_F_SALE_SUM' JOB_NAME, 
      NULL JOB_EXEC_HOUR, 
      NULL 
  FROM DUAL) A, 
 ( SELECT LPAD(ROWNUM-1,2,'0') CNT FROM DBA_TABLES 
     WHERE ROWNUM<25) B 

COMMIT; 

--JOB_LIST를 JOB_LOG로 INSERT(현재 SP_IN_JOB_LOG 가 다음일을 INSERT하도록 되어 있으므로 해당일을 넣어줌) 
EXEC SP_IN_JOB_LOG('20050208'); 


--제대로 들어갔는지 확인 
SELECT * FROM JOB_LOG; 


--SOURCE 테이블을 시간단위로 섬머리 해서 TARGET 테이블로 적재하기 위한 프로시져 
--ERROR없이 매 시간 돌 때는 파라미터 없이 SP_IN_F_SALE_SUM으로 수행 되고 수동으로 어떤 데이터의 
--범위를 적재해야 할 경우 시간의 범위를 파라미터로 넘겨줌 
CREATE OR REPLACE PROCEDURE 
SP_IN_F_SALE_SUM(V_STARTTIME IN VARCHAR2 DEFAULT NULL, 
        V_ENDTIME IN VARCHAR2 DEFAULT NULL) 
AS 
  D_STARTTIME DATE; 
  D_ENDTIME DATE; 
  V_ERR_MSG VARCHAR2(100); 
BEGIN 
  
 --프로시저가 파라미터 값이 없이 수행될 경우 
 IF V_STARTTIME IS NULL AND V_ENDTIME IS NULL THEN 
  SELECT NVL(JOB_DATAEND_TIME,TRUNC(SYSDATE-1/24,'HH24')) 
  INTO D_STARTTIME 
  FROM JOB_LOG 
  WHERE JOB_ID=(SELECT JOB_ID FROM JOB_LIST 
             WHERE JOB_NAME='SP_IN_F_SALE_SUM' 
       AND JOB_EXEC_HOUR=TO_CHAR(SYSDATE-1/24,'HH24')) 
  AND JOB_EXEC_DATE=TO_CHAR(SYSDATE,'YYYYMMDD') 
  AND JOB_STATUS='Y'; 

  D_ENDTIME:=TRUNC(SYSDATE,'HH24'); 
 ELSE 
  SELECT NVL(JOB_DATAEND_TIME,TO_DATE(V_STARTTIME,'YYYYMMDDHH24MISS')) 
  INTO D_STARTTIME 
  FROM JOB_LOG 
  WHERE JOB_ID=(SELECT JOB_ID FROM JOB_LIST 
             WHERE JOB_NAME='SP_IN_F_SALE_SUM' 
       AND JOB_EXEC_HOUR=SUBSTR(V_STARTTIME,9,2)) 
  AND JOB_EXEC_DATE=SUBSTR(V_ENDTIME,1,8) 
  AND JOB_STATUS='Y'; 

  D_ENDTIME:=TO_DATE(V_ENDTIME,'YYYYMMDDHH24MISS'); 
 END IF; 
  
  
 --수행되는 프로시저의 START시간을 찍어주고 RUNNING으로 표시 
 UPDATE JOB_LOG 
 SET JOB_START_TIME=SYSDATE, 
  JOB_STATUS='R' 
 WHERE JOB_ID=(SELECT JOB_ID FROM JOB_LIST 
         WHERE JOB_NAME='SP_IN_F_SALE_SUM' 
      AND JOB_EXEC_HOUR=SUBSTR(V_STARTTIME,9,2)) 
 AND JOB_EXEC_DATE=SUBSTR(V_ENDTIME,1,8); 
  
 -- DML------ 
  
  --수행되어질 INSERT문 
  
 -- DML----- 
  
 COMMIT; 
  
 --프로시저가 ERROR없이 수행이 끝나면 END 시간과 가져온 데이터의 범위를 찍어줌 
 UPDATE JOB_LOG 
 SET JOB_END_TIME=SYSDATE, 
  JOB_DATASTART_TIME=D_STARTTIME, 
  JOB_DATAEND_TIME=D_ENDTIME, 
  JOB_STATUS='Y' 
 WHERE JOB_ID=(SELECT JOB_ID FROM JOB_LIST 
         WHERE JOB_NAME='SP_IN_F_SALE_SUM' 
      AND JOB_EXEC_HOUR=TO_CHAR(D_ENDTIME,'HH24')) 
 AND JOB_EXEC_DATE=SUBSTR(V_ENDTIME,1,8); 
  
 COMMIT; 
  
EXCEPTION 
   WHEN OTHERS THEN 
      V_ERR_MSG:= SUBSTRB(SQLERRM, 1, 80); 
     
     UPDATE JOB_LOG 
     SET JOB_END_TIME=SYSDATE, 
      JOB_STATUS='E', 
      JOB_ERR_MSG=V_ERR_MSG 
           WHERE JOB_ID=(SELECT JOB_ID FROM JOB_LIST 
                  WHERE JOB_NAME='SP_IN_F_SALE_SUM' 
         AND JOB_EXEC_HOUR=TO_CHAR(D_ENDTIME,'HH24')) 
           AND JOB_EXEC_DATE=SUBSTR(V_ENDTIME,1,8); 
     
     COMMIT; 
END SP_IN_F_SALE_SUM; 



--SP_IN_F_SALE_SUM 프로시저를 DBMS_JOB에 등록합니다. 
DECLARE 
    JOB_NUMBER NUMBER; 
BEGIN 
  DBMS_JOB.SUBMIT(JOB_NUMBER,  --JOB번호 
        'SP_IN_F_SALE_SUM;',  --프로시저명 
         TO_DATE('20050209000000','YYYYMMDDHH24MISS'),  --NEXT_DATE 
        'TRUNC(SYSDATE,''MI'')+1/24');  --잡 수행 간격(매시간 정각) 
END; 


JOB의 시간이나 간격 등록된 프로시저등을 변경하고자 할 때 DBMS_JOB의 다른 프로시져를 이용해서 변경합니다. 
2번째 정리 부분에 설명되어 있습니다.

[출처] http://blog.naver.com/gnpado/40017478314 

반응형

'Database & NoSQL > DB' 카테고리의 다른 글

[MS-SQL] mssql Getdate() format 정리  (0) 2014.02.13
다국어 데이터타입 설정  (0) 2014.02.07
oracle job 생성  (0) 2014.01.28
Erwin 설치, 엔티티생성, 관계설정  (0) 2014.01.04
오라클 데이터 이동(merge)  (0) 2014.01.02

oracle job 생성

2014. 1. 28. 09:53
반응형
오라클 JOB CREATE
-- 프로시저 생성
CREATE OR REPLACE PROCEDURE INSERT_TEST_JOB
IS
BEGIN
   INSERT INTO TEST_JOB (NUM, REGDATE)
   VALUES ( (SELECT MAX (NVL (NUM, 0)) + 1 FROM TEST_JOB), SYSDATE);
   COMMIT;
END INSERT_TEST_JOB;

--프로시저 삭제
DROP PROCEDURE insert_test_job;

-- JOB 생성
DECLARE
   JOBNO   NUMBER;
BEGIN
   DBMS_JOB.SUBMIT (JOBNO,
                    'USERS.INSERT_TEST_JOB;',
                    SYSDATE + 1 / 24 / 60,                  -- job이 실행될 시간 1분후
                    'TRUNC(ADD_MONTHS(SYSDATE, 1))+6/24', -- job이 실행되는 간격  매달 1일 6시
                    FALSE);
   COMMIT;
END;
* job Interval 설정 ex) SYSDATE+7 : 7일에 한번 씩 job 수행 SYSDATE+1/24 : 1시간에 한번 씩 job 수행 SYSDATE+30/ : 30초에 한번 씩 job 수행(24: 시간 당, 1440(24x60):분 당, 86400(24x60x60):초 당 ) TRUNC(SYSDATE, 'MI')+8/24 : 최초 job 수행시간이 12:29분 일 경우 매시 12:29분에 job 수행 TRUNC(SYSDATE+1) : 매일 밤 12시에 job 수행 TRUNC(SYSDATE+1)+3/24 : 매일 오전 3시 job 수행 NEXT_DAY(TRUNC(SYSDATE),'MONDAY')+15/25 : 매주 월요일 오후 3시 정각에 job 수행 TRUNC(LAST_DAY(SYSDATE))+1 : 매월 1일 밤 12시에 job 수행 TRUNC(LAST_DAY(SYSDATE))+1+8/24+30/1440 : 매월 1일 오전 8시 30분
--JOB 삭제
execute dbms_job.remove(잡번호);

--JOB 조회
SELECT WHAT, JOB, NEXT_DATE, NEXT_SEC, FAILURES, BROKEN FROM USER_JOBS;

* job queue 정보 VIEWING
 SELECT * FROM DBA_JOBS
 SELECT * FROM USER_JOBS
 SELECT * FROM ALL_JOBS
반응형
반응형

ERWIN을 쓸일이 있어서 이것저것 찾아보다.. 아주 기초적으로 정리를 잘 해놓은 파일이 있어서 공유 합니다.

문제 있다면 내리구요~~~

1. Er-win 설치 : 는 생략... 그냥 설치하는 것은 어렵지 않아요
2. Er-win 표기 방식 : IE 와 Ideflx 에 대한 설명
3. 엔티티 생성 방법
4. 식별/비식별, 다대다 관계 예제 
 ***   관계(Relationship) : 두 Entity간의 업무적인 연관성
  1) 식별관계( Identifying Relationship) 
    - 부모 테이블의 기본키 or 복합키가 자식 테이블의 기본키 or 복합키의 구성원으로 전이되는 식별 관계
      (부모가 자식의 모든 정보를 저장하게 됨)
  2) 비식별관계(Non Identifying Relationship)
     - 자식 테이블의 일반 속성(Attribute) 그룹의 구성원으로 전이 되는 비식별관계(부모는 자식의 부분적인 정보를 표현함)

   * A Table이 부모이고, B Table이 자식Table 일때, B에서 FK
     (A와 B를 연결해주는 컬럼, 즉 A의 PK이냐 아니냐에 따라 식별관계와 비식별 관계로 나뉘게 됨.)
   * 식별관계는 B테이블은 A테이블에 종속적이 되어서 A의 값이 없으면 B의 값은 무의미해 지는 것인 
      반면에 비식별관계는 A 의 값이 없더라도 B의 값은 독자적으로 의미를 가짐.

 ERD를 작성할 때 필요한 관계 카디낼리티와 선택성의 표시 기호와 의미는 다음과 같습니다.
1. 실선 : 식별관계 - 부모테이블의 PK가 자식테이블의 FK/PK가 되는 경우
2. 점선 : 비식별관계 - 부모테이블의 PK가 자식테이블의 일반속성이 되는 경우
3. O : Optional(선택) - 0개가 될 수 있다.
4. | : Mandatory - 1개가 될 수 있다.
5. ^ : Many - 여러개가 될 수 있다.
6. - : Exactly - 정해진 개수만 될 수 있다.

5. 슈퍼 타입과 서브 타입
6. 재귀적 관계 정의
7. Erwin Domain 설정  : 이것 말고 사실 Naming 설정하는 것도 있는데 이거 정말 편함.(http://www.dator.co.kr/eyelevel/textyle/218797)
8. Erwin 
물리적 DB 모델링 설계 방법 
9. 인덱스 정의 
10. 스키마 생성...

 

간략 목차 정리 드렸습니다.
감사합니다.

 마지막으로 다시 정리 하면

식별관계(Identifying Relationship)
 부모 엔티티의 주식별자(PK)는 관계(Relationship)을 통해 자식 엔티티의 외부식별자(FK)로 이주하고, 이주한 부모의 주 식별자(PK)는 자식의 주 식별자(PK)의 일부가 된다. -> (PK,FK)
자식은 각 인스턴스를 식별하기 위해 부모에 종속적이고, 부모 없이는 존재할 수 없다.

비식별관계(Non-Ientifying Relationship)
-  
부모 엔티티에 종속적인지 비종속적인지의 여부에 따라 다시 두 가지 관계로 나뉜다.


비식별종속관계 (Non-Identifying Mandatory Relationship)
부모의 주 식별자는 자신의 non-key 영역으로 이주하고, 자신을 식별하는 데 관계하지 않는다.
자식은 자신의 각 인스턴스의 식별을 위해 부모 엔티티에 독립적이고, 부모 없이 존재할 수 없다.
비식별비종속관계(Non-Identifying Non-Mandatory Relationship)
부모의 주 식별자는 자신의 non-key 영역으로 이주하고, 자신을 식별하는 데 관계하지 않는다.
자식은 자신의 각 인스턴스의 식별 위해 부모 엔티티에 독립적이고, 부모없이 존재할 수도 있다.

http://kimseunghyun76.tistory.com 퍼옴.

반응형

'Database & NoSQL > DB' 카테고리의 다른 글

오라클 잡 관리(Oracle job manage)  (0) 2014.01.28
oracle job 생성  (0) 2014.01.28
오라클 데이터 이동(merge)  (0) 2014.01.02
오라클 세로행을 가로 출력(LISTAGG)  (0) 2013.03.22
오라클 시간 연산(SYSDATE)  (0) 2013.03.22
반응형

이번글은 MERGE 문을 이용해 데이터를 이동시켜보는 방법에 대해서 알아보겠습니다.

MERGE 문은 오라클 9i 버전부터 사용하실 수 있습니다.

MERGE문은 언제 쓰면 될까요?



위의 그림처럼 테이블1의 데이터를 테이블2로 복사하려고 합니다.

그런데 테이블1의 내용 중 몇개가 테이블2에 들어있기때문에 INSERT를 하려면 에러가 발생하게 되어 UPDATE 문으로 처리를 해주어야합니다.

하지만 MERGE문을 이용하면 테이블1과 테이블2를 비교하여 테이블1의 내용이 테이블2에 존재하면 UPDATE 존재하지않으면 INSERT 시켜줄 수 있습니다.
(프로그래밍 언어의 IF ~ ELSE ~ 문과 비슷합니다.)

그럼 이제 사용법을 알아보겠습니다.

일단 2개의 테이블을 만들었습니다. 두 테이블에는 NO, NAME, AGE 3개의 컬럼을 가지고 있습니다.

 


일단 1번 테이블 TEMP_TAB_1 테이블에 데이터를 입력했습니다.

DECLARE ~ BEGIN ~ END; 는 PL/SQL 문법으로 아직 설명한적은 없지만 INSERT INTO를 9번 실행하기가 귀찮아서 그냥 썼습니다.

지금 중요한건 이게 아니니까 사용법만 알려드리겠습니다.

ed or edit 명령어를 이용해서 버퍼(이곳에는 바로전에 사용되어진 명령어가 저장되어있습니다.)를 불러와서 다음과 같이 입력합니다.
(아래의 내용은 이 글 처음의 MERGE 예제 텍스트 파일에 첨부되어있습니다. )

 


 ※ ED or EDIT 명령어를 사용했는데 아래와 같이 나올경우는 버퍼에 아무런 내용이 안들어있기 때문입니다.
    이때에는 select 1 from dual; 같은 명령어를 한번 입력하고 불러오시면 됩니다.

 


입력한 후에 R 또는 RUN 명령어를 사용하여 버퍼에 기록되어진 쿼리를 실행합니다.

그럼 테이블1에 데이터입력 끝!

 


테이블 2에는 테이블1의 일부내용만 입력합시다.


이제 극단적인 예를 들어보겠습니다.

 사장님이 TEMP_TAB_2 에 TEMP_TAB_1의 내용을 복사해서 다 집어넣으라고 하시는군요?

거기다가 이름앞에는 소녀시대_ 를 집어넣고 나이는 해가 지났으니 1살씩 더 추가하라고 하십니다. 어찌해야할까요..

사장님이 이렇게 쉬운문제를 줄리는 없지만 이럴때 MERGE 문을 사용하면 됩니다.

다음이 MERGE문의 사용방법입니다.


MERGE INTO 복사당할테이블명 테이블별칭
   USING 복사할테이블명 테이블별칭
   ON (JOIN 조건)
WHEN MATCHED THEN                                       --복사당할 테이블에 복사할 테이블 데이터가 들어있을경우
   UPDATE SET
            t2.name      = '소녀시대_' || t1.name
           ,t2.age         = t1.age + 1
WHEN NOT MATCHED THEN                               --복사당할 테이블에 복사할 테이블 데이터가 없을경우
   INSERT VALUES(
             t1.no
           , '소녀시대_' || t1.name
           , t1.age + 1
   )

※ INSERT(컬럼명1, 컬럼명2, ...) VALUE(컬럼1내용, 컬럼2내용, ..) 처럼 일부컬럼에만 INSERT 할 수도 있습니다.
※ USING ON은 이전글인 [Oracle] Join 방법에 대해 알아봅시다 에서 4번 JOIN-ON 과 같은 형식입니다.

다음은 실행결과입니다. 테이블1의 내용이 테이블2로 정상적으로 복사된것을 보실 수 있습니다.


http://breadshuttle.tistory.com/ 퍼옴.

반응형
반응형
▣오라클 LISTAGG (11g) 
 쿼리 질의시에 세로로 출력되는 필드를 하나에 필드에 구분자를 넣어 출력
SELECT LISTAGG(필드, '|') WITHIN GROUP(ORDER BY 정렬할 필드) 
FROM 테이블명


반응형

'Database & NoSQL > DB' 카테고리의 다른 글

오라클 잡 관리(Oracle job manage)  (0) 2014.01.28
oracle job 생성  (0) 2014.01.28
Erwin 설치, 엔티티생성, 관계설정  (0) 2014.01.04
오라클 데이터 이동(merge)  (0) 2014.01.02
오라클 시간 연산(SYSDATE)  (0) 2013.03.22

+ Recent posts

반응형