반응형

오라클 백업에는 크게 피지컬 백업(Physical Backup) 방식과 로지컬 백업(Logical Backup) 방식이 있다.

피지컬 백업 방식이란 데이타 파일 자체를 카피하는 방식을 말하는데, 이것은 다시 데이타베이스를 셧다운하고 백업하는 방식과 오픈된 상태에서 백업하는 방식으로 나뉜다. 반면, 로지컬 백업 방식이란 오라클에서 제공하는 유틸리티 중의 하나인 Export/Import를 이용하여 백업하는 형식으로, 이 백업 파일을 이용하여 리커버리를 실행하면 Create Object 문장을 이용해 테이블스페이스와 유저, 테이블을 생성하고, Insert Statement를 이용해 특정 테이블에 Insert 작업이 이루어지기 때문에 이처럼 일컫는 것이다.

먼저 이들에 대해 각각 알아보고, 데이타 복구(Recovery)를 위한 기본 개념들을 다루고자 한다. 그리고 리커버리에 대한 더 구체적인 설명은 다음 호에서 다룰 예정이다.


Cold Backup 받는 방법

콜드 백업(Cold Backup)은 데이타베이스가 정상적으로 셧다운된 상태에서 데이타 파일, 로그 파일, 콘트롤 파일을 모두 백업 받는 것을 말한다. 셧다운하지 않고 오픈된 상태에서 백업을 받으면 백업 받은 내용을 나중에 사용할 수가 없으므로 유의해야 한다.
콜드 백업을 위해서 데이타베이스를 셧다운할 때에는 Normal 또는 Immediate 옵션을 사용해야 하며, Abort를 사용해서는 안 된다.
상황이 여의치 않아 Abort를 사용한 경우에는 셧다운 후에 다시 스타트업하고 Normal로 셧다운한 후 백업을 받도록 한다.

우선 이들 파일을 백업하기 위해 콘트롤 파일과 데이타 파일 및 로그 파일의 위치를 확인하여 이들을 tar, cpio, dd 등의 명령을 이용하여 백업 받도록 한다. NT에서는 Copy 명령이나 탐색기를 이용해서 백업을 받으면 된다.

 

■ 콘트롤 파일 확인 방법
sqlplus에 system/manager로 접속 후
SQL>select value from v$controlfile;

■ 데이타 파일 확인 방법
SQL>select name from v$datafile;

■ 로그 파일 확인 방법
SQL>select member from v$logfile;

 

이처럼 각각의 파일 위치를 확인하여 위에서 확인된 3종류의 파일들을 백업 받으면 된다. 이때 오라클은 반드시 셧다운된 상태이어야 한다. 항상은 아니지만 필요에 따라서는 패러미터 파일까지 받아두는 것이 좋다. 패러미터 파일은 $ORACLE_HOME/dbs/init.ora에 있는데, 이 초기화 패러미터 파일에 기술되어진 패러미터는 시스템의 성능에 주요한 역할을 하므로 이 파일이 없어진 경우에 예전의 성능을 유지하려면 이 파일을 필수적으로 백업해야 한다.

 

NT에서는 C:\ORANT\DATABASE\init.ora 파일이다.

일반적으로 NT의 SID가 처음 만들어질 때 ORCL이므로 이 초기 패러미터 파일 역시 initORCL.ora라고 되어 있다.

여기서 는 오라클 인스턴스 이름으로 환경변수 ORACLE_SID로 지정되어 있다. 이 ORACLE_SID는 Unix의 경우 $env, NT의 경우는 Registry에 지정되어 있으므로 직접 확인해 볼 수 있다.


Hot Backup 받는 방법


핫 백업(Hot Backup)이란 데이타베이스를 셧다운하지 않고 백업하는 방식으로, 일반적인 경우는 적용되지 않고 자신의 데이타베이스를 Archive Mode로 운영하는 경우에만 가능하다.
콜드 백업을 이용하여 데이타를 복구하는 경우에는 콜드 백업을 받은 시점까지만 복구가 가능한 데 반해, 이 Archive 방식으로 데이타베이스를 운영하는 경우에는 사용자가 원하는 시점까지 데이타를 복구할 수 있다. 즉, 원하는 시간을 주어서, SCN 번호를 주어서, 혹은 어느 데이타 파일 한 개만의 복구도 가능하다.

데이타 복구만 생각한다면 모든 데이타베이스를 Archive 방식으로 운영하는 것이 좋겠지만, 이 방식을 사용하는 경우 데이타베이스 관리자가 백업/리커버리에 관하여 많은 지식과 경험을 갖춰야 하며, 또 Archive Log를 계속 유지관리하는 데는 스페이스와 성능의 부하가 따르기 때문에 사용자의 적절한 판단에 의하여 이용하도록 한다.

그러면 Archive Log Mode의 운영 방법에 대해 알아보자.


Archive Log Mode 운영 방법

오라클에서 데이타베이스가 셧다운되지 않은 상태에서 백업을 받거나 문제가 생긴 시점까지의 완벽한 리커버리 작업을 수행하기 위해서는 데이타베이스를 아카이브 로그 모드로 운영하여야 한다.

아카이브 로그 모드로 운영하기 위해서는 다음의 절차에 따라 변경하여야 한다.

 

1. initSID.ora 파일과 configSID.ora에 다음의 패러미터가 이미 설정되어 있는지 확인한 후에 없을 경우 initSID.ora에 설정한다.

(1) LOG_ARCHIVE_START = TRUE

이 패러미터에 의해 데이타베이스가 처음 구동시 ARCH 프로세스가 기동.

Log Switch 발생시 Automatic Archive를 수행한다.

만약 이 패러미터가 False이면 Manual Archive를 수행한다.
(2)LOG_ARCHIVE_DEST =/home/oracle8/dbs/archive_file/arc 
아카이브 파일이 생성되는 위치인 디렉토리와 확장자를 포함하지 않는 파일명을 지정.

여기에서 archive_file까지는 디렉토리이며 마지막에 있는 arc는 아카이브 로그 파일 이름의 첫 부분이다. 
이 아카이브 로그 모드를 설정하면 로그 파일의 스위치가 일어날 때마다 지속적으로 이 Log_Archive_Dest에 지정한 위치에 로그 파일이 쌓이게 되는데, 만일 부주의에 의해 이 아카이브 로그 파일이 깨지거나 분실되는 경우는 그 이후의 데이타 복구가 불가능하므로 주의하여야 한다.

이러한 문제를 줄이기 위해 Oracle8부터는 아카이브 로그 파일을 Mirroring하기 위하여 여러 군데에 보관할 수 있는 방안도 도입되었다. 이는 log_archive_duplex_dest를 설정함으로써 가능하다.

또한 V8i부터는 최대 5군데에 이 로그 파일을 저장할 수 있도록 하여

LOG_ARCHIVE_DEST_1=”Location=/oracle8/arch_1 MANDATORY”
LOG_ARCHIVE_DEST_2=”Location=/oracle8/arch_2 OPTIONAL?

처럼 지정이 가능하다

(3) LOG_ARCHIVE_FORMAT = %s.log
아카이브 파일의 확장자와 로그 시퀀스 번호의 형식을 지정.

이는 (2)에서 정의된 아카이브 로그 파일의 첫 부분 이름과 함께 나타난다.
arc123.log, arc124.log (123과 124는 로그 시퀀스 번호)
와 같은 형태의 파일이 지정한 위치에 생성된다.

 

2. 다음과 같이 작업하여 아카이브 로그 모드로 변환한다.

$ svrmgrl

SVRMGR> connect internal
SVRMGR> startup mount - ■
SVRMGR> alter database archivelog; - □
SVRMGR> archive log list - ●
Database log mode ARCHIVELOG - ◎
Automatic archival ENABLED - ◇
Archive destination ?/dbs_ar/offline_log/offline - ◆
Oldest online log sequence 123 - △
Next log sequence to archive 125 - ▲
Current log sequence 125 - ▷
SVRMGR> alter database open; - ▶

■ DB를 Startup Mount까지만 한다.
□ 이 커맨드를 이용하여 아카이브 모드로 데이타베이스를 변경한다.
● 아카이브 모드로 변경되었는지를 확인한다.
◎ 데이타베이스가 아카이브 모드임을 나타낸다. 만약 NOARCHIVELOG로 되어 있으면 변경되지 않은 것을 의미한다.
◇ initSID.ora 파일에서 LOG_ARCHIVE_START 패러미터를 TRUE로 정의하였음을 나타내며 False인 경우에는 DISABLED로 나타난다.
◆ initSID.ora 파일의 LOG_ARCHIVE_DEST 패러미터에서 정의한 아카이브할 장소이다.
△ 3개의 Redo Log 중 가장 오래된 리두 로그의 시퀀스가 123임을 의미한다.
▲ 다음에 아카이브 받을 파일의 로그 시퀀스 번호를 나타낸다.
▷ 현재 사용중인 리두 로그의 시퀀스가 125임을 의미한다. 만약 이전부터 아카이브 로그 모드로 운영중이었다면 여기에서 아카이브 로그 파일은 로그 시퀀스 124까지 아카이브되어 있다는 것을 의미한다.
▶ 아카이브 모드로 변경 후 DB를 오픈한다.


No Archive Log Mode로 전환하는 방법
반대로, Archivelog Mode에서 No Archivelog Mode로 전환하는 방법은 다음과 같다.

먼저, 위에서 세팅했던 initSID.ora 파일과 configSID.ora에 있는 다음 패러미터 앞에 #을 넣고 저장한다.
#LOG_ARCHIVE_START = TRUE
#LOG_ARCHIVE_DEST = /home/oracle8/dbs/archive_file/arc
#LOG_ARCHIVE_FORMAT = %s.log

$ svrmgrl
SVRMGR> connect internal;           
SVRMGR> shutdown immediate
SVRMGR> startup mount           
ORACLE instance started.           
Database mounted.           
SVRMGR> alter database noarchivelog;     
Statement processed.           
SVRMGR> alter database open;           
Statement processed.


Hot Backup 하는 방법

데이타베이스를 셧다운하지 않고 데이타 파일을 백업하는 방법이다.
이 방법은 콜드 백업보다 더 복잡하지만 데이타베이스가 오픈되어 있는 도중에 할 수 있고 또한 테이블스페이스 별로 백업할 수 있다는 장점이 있다.
핫 백업은 항상 데이타베이스를 아카이브 로그 모드 상태로 두고 실시한다.

| 방법 | 테이블스페이스 단위로 백업을 실시한다.
svrmgrl > CONNECT INTERNAL

svrmgrl > ALTER TABLESPACE SYSTEM BEGIN BACKUP;

시스템 테이블스페이스의 모든 데이타파일에 대해서 OS Backup 한다.

$ tar cvf /dev/rmt0 /usr/oracle8/dbs/syst1ORA8.dbf

$ tar cvf /dev/rmt0 /usr/oracle8/dbs/syst2ORA8.dbf

svrmgrl > ALTER TABLESPACE SYSTEM END BACKUP;

svrmgrl > ALTER TABLESPACE USERS BEGIN BACKUP;

$ tar cvf /dev/rmt0 /usr/oracle8/dbs/user1ORA8.dbf

svrmgrl > ALTER TABLESPACE USERS END BACKUP;

다른 테이블스페이스에 대해서도 같은 방법으로 한다.


주의할 점은 BEGIN과 END 사이에는 해당 테이블스페이스의 데이타파일 헤더 정보가 변경되지 않는다는 것이다. 따라서 OS 백업이 종료됨과 동시에 ‘ALTER TABLESPACE ... END BAKCUP’ 커맨드를 실행하여 데이타파일의 헤더가 변경되도록 한다.
이 아카이브 백업 파일을 이용한 복구 방법은 다음 기회에 다루도록 한다.


Export Backup 하는 방법

오라클에서 제공되는 Export 유틸리티는 데이타베이스에 저장된 데이타를 바이너리 형태의 OS 파일로 만들고, 필요시 Import 유틸리티를 이용하여 데이타베이스로 다시 올리는 방식이다 .
이 유틸리티는 각 오브젝트 단위로 처리가 가능하기 때문에 테이블 몇 개만을 복구한다든가 특정 사용자의 테이블들을 다른 테이블스페이스로 옮긴다든가 또는 전체 데이타베이스의 자료를 서로 다른 OS로 옮기는 경우 등에 특히 유리하다.


Export의 종류

이 Export 방안은 시스템과 서로 메시지를 주고받으면서 백업을 할 수 있는 Interactive Mode가 있고, 한 라인의 명령어로 Export시 필요한 옵션을 길게 열거해주는 Command 방식이 있다.
Command 방식은 순간 순간 필요한 옵션을 적어주기만 하면 되기 때문에 여기서는 Interactive 방식을 다루어 보기로 한다


Export의 단위

 

Full 단위 : 전체 데이타베이스를 Export 한다.
User 단위 : 특정 유저 전체 오브젝트를 Export 한다.
Table 단위 : 특정 테이블을 Export 한다.
Partition 단위 : 특정 테이블의 파티션을 Export 한다.

Export의 실제 예제
| 예 1 | 전체 데이타베이스의 Export (Interactive Method)

$ exp system/manager
Connected to: ORACLE8 Server Release 8.0.5 - Production

With the procedural and distributed options
PL/SQL Release 2.2 - Production
Enter array fetch buffer size : 4096 > 100000 (RETURN)
Export file : expdat.dmp >
(1) E(ntire database), (2) U(sers), (3) T(ables) : U > e
Export grants (Y/N) : Y > y
Export table data (Y/N) : Y > y
Compress extents (Y/N) : Y > y
About to export the entire database....

. exporting tablespace definitions
. exporting profiles
. exporting user definitions
. exporting role
. exporting rollback segment definitions
. exporting database links
. exporting sequence numbers
. exporting sequence numbers
. exporting cluster definitions
. exporting stored procedures
. about to export SYSTEM’s tables ...
. about to export SCOTT’s tables ...
. exporting synonyms
. exporting views
. exporting referential integrity constraints
. exporting triggers

Export terminated successfully without warnings.
| 예 2 | 전체 데이타베이스의 EXPORT(Command Line Method)

$ exp userid=system/manager full=y file=fullbackup.dmp buffer=100000
| 예 3 | 전체 데이타베이스의 EXPORT(Dynamic Method)
Export 패러미터를 다음과 같은 파일(tusc.par) 형태로 만든다.

system/manager
full=y
file=fullbackup.dmp
buffer=100000
$ exp parfile=tusc.par

| 예 4 | User 단위의 Export

$ exp system/manager
Connected to: ORACLE8 Server Release 8.0.5 - Production

With the procedural and distributed options
PL/SQL Release 2.2 - Production
Enter array fetch buffer size : 4096 > 100000 (RETURN)
Export file : expdat.dmp >
(1) E(ntire database), (2) U(sers), (3) T(ables) : U > u
Export grants (Y/N) : Y > y
Export table data (Y/N) : Y > y
Compress extents (Y/N) : Y > y

About to export specified users
User to be exported: (RETURN to quit) > scott
. exporting snapshots
. exporting snapshot log
. exporting database links
. exporting sequence numbers
. exporting sequence numbers
. exporting cluster definitions
. exporting stored procedures
. about to export SCOTT’s tables ...
. exporting synonyms
. exporting views
. exporting referential integrity constraints
. exporting triggers
Export terminated successfully without warnings.

| 예 5 | User 단위의 Export (Command Line Method)

$ exp system/manager owner=scott file=scott.dmp buffer=100000

또는

$ exp scott/tiger file=scott.dmp buffer=100000

| 예 6 | User 단위의 Export (Dynamic Method )
Export 패러미터를 다음과 같은 파일(tusc.par) 형태로 만든다.

$vi tusc.par

scott/tiger
file=scott.dmp
buffer=1000000
$ exp parfile=tusc.par

| 예 7 | Table 단위의 Export

$ exp scott/tiger file=table.dmp tables=emp,dept buffer=100000

 

반응형

'Database > ORACLE' 카테고리의 다른 글

DBMS_JOB PACKAGE의 사용 방법과 예제  (0) 2009.03.08
INVALID OBJECT 컴파일 하는 방법  (0) 2009.03.08
TAB 뷰 에 정보 생성하기  (0) 2009.03.08
SQL LOADER 사용예  (0) 2009.03.08
PL/SQL 에서 DDL 문장 호출하기  (0) 2009.03.08
반응형


흔히 SELECT * FROM TAB을 하면 테이블 정보를 조회 가능하다.

TAB는 뷰이다 ! 

-- SYSDBA 계정 으로 생성

CREATE OR REPLACE VIEW SYS.TAB
(TNAME,TAB,CLUSTERID)
AS
select o.name,
    decode(o.type#, 2, 'TABLE', 3, 'CLUSTER',
           4, 'VIEW', 5, 'SYNONYM'), t.tab#
from  sys.tab$ t, sys.obj$ o
where o.owner# = userenv('SCHEMAID')
and o.type# >=2
and o.type# <=5
and o.linkname is null
and o.obj# = t.obj# (+)

 

-- 다른 계정에서 동의어로 가지고 오기

CREATE SYNONYM tab FOR  SYS.TAB;

반응형
반응형

익명님이 말씀하신대로 그대로 읽을 수는 없습니다.
그러나 엑셀 파일을 csv파일로 저장하셔서 서버에 올리시면 읽을 수 있습니다.
오라클 샘플 데이터인 emp테이블을 예로 들어 설명 하겠습니다.

아래에서 보시는 것처럼 엑셀데이터를 cvs로 저장하여 올리시면...
emp.csv 처럼 보입니다.
이를 이용하기 위해 테이블 구조에 맞추어 EMP.ctl을 작성 하시고....
실행 시켜 주심 됩니다.
이행 해야 할 데이터가 많다면... 스크립트를 미리 한방에 만들어 하심이 편하실겁니다.

====================================================================
SQL> desc emp
 Name                            Null?    Type
 ------------------------------- -------- ----
 EMPNO                           NOT NULL NUMBER(4)
 ENAME                                    VARCHAR2(10)
 JOB                                      VARCHAR2(9)
 MGR                                      NUMBER(4)
 HIREDATE                                 DATE
 SAL                                      NUMBER(7,2)
 COMM                                     NUMBER(7,2)
 DEPTNO                                   NUMBER(2)

SQL> select * from emp;

     EMPNO ENAME      JOB              MGR HIREDATE        SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 19801217        800                    20     
      7499 ALLEN      SALESMAN        7698 19810220       1600        300         30     
      7521 WARD       SALESMAN        7698 19810222       1250        500         30     
      7566 JONES      MANAGER         7839 19810402       2975                    20     
      7654 MARTIN     SALESMAN        7698 19810928       1250       1400         30     
      7698 BLAKE      MANAGER         7839 19810501       2850                    30     
      7782 CLARK      MANAGER         7839 19810609       2450                    10     
      7788 SCOTT      ANALYST         7566 19821209       3000                    20     
      7839 KING       PRESIDENT            19811117       5000                    10     
      7844 TURNER     SALESMAN        7698 19810908       1500          0         30     
      7876 ADAMS      CLERK           7788 19830112       1100                    20     
      7900 JAMES      CLERK           7698 19811203        950                    30     
      7902 FORD       ANALYST         7566 19811203       3000                    20     
      7934 MILLER     CLERK           7782 19820123       1300                    10     
     
14 rows selected.


==================================================== EMP.ctl
LOAD DATA
INFILE 'emp.csv'
INTO TABLE EMP
FIELDS TERMINATED BY "," (
EMPNO
, ENAME
, JOB
, MGR
, HIREDATE
, SAL
, COMM
, DEPTNO
)
==================================================== emp.csv
7369,SMITH ,CLERK    ,7902,19801217,800,    ,20
7499,ALLEN ,SALESMAN ,7698,19810220,1600,300,30
7521,WARD  ,SALESMAN ,7698,19810222,1250,500,30
7566,JONES ,MANAGER  ,7839,19810402,2975,    ,20
7654,MARTIN,SALESMAN ,7698,19810928,1250,1400,30
7698,BLAKE ,MANAGER  ,7839,19810501,2850,    ,30
7782,CLARK ,MANAGER  ,7839,19810609,2450,    ,10
7788,SCOTT ,ANALYST  ,7566,19821209,3000,    ,20
7839,KING  ,PRESIDENT,    ,19811117,5000,    ,10
7844,TURNER,SALESMAN ,7698,19810908,1500,0,30
7876,ADAMS ,CLERK    ,7788,19830112,1100,    ,20
7900,JAMES ,CLERK    ,7698,19811203,950,    ,30
7902,FORD  ,ANALYST  ,7566,19811203,3000,    ,20
7934,MILLER,CLERK    ,7782,19820123,1300,    ,10
====================================================  sqlldr 실행
sqlldr username/password control=EMP.ctl direct=true

 

출처 : 데이터베이스 사랑넹

ohyouknow님이 2007-01-12 12:38:29에 작성한 댓글입니다

http://database.sarang.net/?inc=read&aid=29358&criteria=oracle&subcrit=&id=&limit=20&keyword=sqlload&page=1

반응형
반응형

PL/SQL문 내에서

"EXECUTE IMMEDIATE " 를 통해 호출 가능하다


  begin
    EXECUTE IMMEDIATE 'CREATE TABLE TEMP(CRE_DT SYSDATE)';
 end;

반응형
반응형

       CREATE TABLE SOURCE_HIST                     -- Create history table
          AS SELECT SYSDATE CHANGE_DATE, USER_SOURCE.*
             FROM   USER_SOURCE WHERE 1=2;

        CREATE OR REPLACE TRIGGER change_hist        -- Store code in hist table
               AFTER CREATE ON SCOTT.SCHEMA          -- Change SCOTT to your schema name
        DECLARE
        BEGIN
          if DICTIONARY_OBJ_TYPE in ('PROCEDURE', 'FUNCTION',
                          'PACKAGE', 'PACKAGE BODY', 'TYPE') then
             -- Store old code in SOURCE_HIST table
             INSERT INTO SOURCE_HIST
                SELECT sysdate, user_source.* FROM USER_SOURCE
                WHERE  TYPE = DICTIONARY_OBJ_TYPE
                  AND  NAME = DICTIONARY_OBJ_NAME;
          end if;
        EXCEPTION
          WHEN OTHERS THEN
               raise_application_error(-20000, SQLERRM);
        END;
        /
        show errors

[출처] pl/sql|작성자 신머루

반응형

'Database > ORACLE' 카테고리의 다른 글

SQL LOADER 사용예  (0) 2009.03.08
PL/SQL 에서 DDL 문장 호출하기  (0) 2009.03.08
오라클 탭 출력하기  (0) 2009.03.08
오라클 패키지 백업 스크립트  (0) 2009.03.08
오라클 패키지 백업 프로그램  (2) 2009.03.08
반응형

CHR(9) => DBMS.output에서 탭값 출력하기

엑셀에 바로 붙여넣기 귀찮아서 ... ㅋㅋ;

값을 쉽게 구하자..

 또한 & 표시는 CHR(38) 번.

PL/SQL 구문은 & 표시는 값을 입력받도록 되어 있어

REPLACE 구문으로 입력받은 값을 치환할 때 컴파일이 정상적으로 되지 않을수 있음...



간단한 C...를 통해 CHR값을 출력 할 수 있다.

#include <stdio.h>

void main()
{
   char a='\t';
   printf("%d", a);
}

반응형
반응형

1. pkg_backup.sh 파일내용

###  오라클 환경 설정(.profile 참조)

###

sqlplus -SILENT 아뒤/패스워드

@/oracle/backup_pkg/get_pkg_name.sql > names.txt

yd=`date +%Y%m%d`
mkdir -p /oracle/backup_pkg/pkgs/$yd
for get_name in `cat names.txt`
do
        echo "$get_name Package Header Backup"
        echo "set heading off ;" > get_pkg.sql

        echo "set linesize 10000;" >> get_pkg.sql
        echo "set pagesize 50000; " >> get_pkg.sql

        echo "set feedback off; " >> get_pkg.sql
        echo "set verify off;" >> get_pkg.sql

        echo "SELECT TEXT FROM ALL_SOURCE " >> get_pkg.sql
        echo "WHERE TYPE='PACKAGE'" >> get_pkg.sql
        echo "AND   OWNER=''"    >> get_pkg.sql
        echo "AND   NAME='$get_name';" >> get_pkg.sql

        echo "exit; " >> get_pkg.sql

        chmod +x get_pkg.sql

        echo "CREATE OR REPLACE " > /oracle/backup_pkg/pkgs/$yd/$get_name.pks

        sqlplus -SILENT 아뒤/패스워드 @get_pkg.sql >> /oracle/backup_pkg/pkgs/$yd/$get_name.pks


        echo "$get_name Package Body Backup"
        echo "set heading off ;" > get_pkg.sql

        echo "set linesize 10000;" >> get_pkg.sql
        echo "set pagesize 50000; " >> get_pkg.sql

        echo "set feedback off; " >> get_pkg.sql
        echo "set verify off;" >> get_pkg.sql

        echo "SELECT TEXT FROM ALL_SOURCE " >> get_pkg.sql
        echo "WHERE TYPE='PACKAGE BODY'" >> get_pkg.sql
        echo "AND   OWNER=''"    >> get_pkg.sql
        echo "AND   NAME='$get_name';" >> get_pkg.sql

        echo "exit; " >> get_pkg.sql

        chmod +x get_pkg.sql

        echo "CREATE OR REPLACE " > /oracle/backup_pkg/pkgs/$yd/$get_name.pkb

        sqlplus -SILENT 아뒤/패스워드 @get_pkg.sql >> /oracle/backup_pkg/pkgs/$yd/$get_name.pkb


done
cd -

2. get_pkg_name.sql  파일내용

-- 헤더 정보 출력되지 않게 설정
set heading off;

-- 페이지 사이즈를 최대한으로
set pagesize 10000;

-- 출력되는 행수 삭제
set feedback off;

set verify off;

-- 패키지의 이름을 가지고 옴
SELECT NAME FROM ALL_SOURCE
WHERE TYPE='PACKAGE'
AND   OWNER=''
GROUP BY NAME;

-- 종료
exit;

반응형
반응형

물론 난 백업 스크립트를 사용해서 백업하지만

윈도우 상에서 일괄적으로 백업 받을때

(낱개로는 TOAD등 툴을 통해 받을수 있지만...)

사용하면 좋은 프로그램...


프로시져백업.zip


반응형
반응형

본 자료는 일본 @IT(http://www.atmarkit.co.jp/fdb/index/index-db.html#sqlclinic)에 株式会社インサイトテクノロジー의 大道隆久씨가 연재한 SQLクリニック를 번역 재구성한 것입니다.

 

본연재는 SQL의 응용력을 가추고 싶은 엔지니어를 위해 다양한 테크닉을 소개한다. SQL의 기본 구문은 평이한 것이지만, 실무로 활용하려면  교과서적인 기술을 이해하는 것만으로는 불충분하다. 본연재는 저명한 메일 매거진 「오라!오라! Oracle - 듬뿍 검증 생활」을 발행하는 인사이트 테크놀로지의 컨설턴트를 집필진으로 맞이해 SQL의 센스 향상에 도움이 되는 각족 기술을 소개한다. 

 

## 테스트로 사용하는 샘플 테이블은 위의 링크로 부터 다운가능합니다.

 

 

Oracle 10g로 정규표현에 의한 문자열 조작 가능!!!


Oracle Database 10g부터 신규로 추가된 정규 표현 기능은 텍스트 형식 데이터를 취급하기 위한 강력한 툴입니다. 이것으로 SQL를 사용한 문자 데이터를 검색, 조작하는 능력이 큰폭으로 향상됩니다.

 

지금까지는 WHERE구 안에서 “LIKE”와 함께 사용하는 「%」나 「_」등에서 밖에 표현할 수 없었다 이제 애매한 문자열을 정규 표현을 사용해 문자수나 그 종류까지 지정할 수 있게 되었으므로 편리해 졌네요... 

Oracle 10g부터 서포트되는 정규 표현(REGEXP_LIKE, REGEXP_INSTR, REGEXP_SUBSTR, REGEXP_REPLACE 함수)을 소개합니다.

 

Oracle10g로 추가된 새로운 함수


Oracle9i까지 존재했던 함수에 「REGEXP_」를 붙여 정규 표현용의 함수가 준비되었습니다.(표1 참조) 차례로 조작 방법을 확인해 보게습니다. 

함수명칭

구문

설명

REGEXP_LIKE

REGEXP_LIKE(
    열명,
    조건
)

조건(정규 표현)을 사용해 애매한 조건 검색을 실시합니다 .검색 대상열에서는 문자 데이터형을 서포트합니다(CHAR, VARCHAR2, CLOB, NCHAR, NVARCHAR2 및 NCLOB는 서포트합니다만, LONG는 서포트하지 않습니다)

REGEXP_INSTR

REGEXP_INSTR(
    문자열 또는 열명,
    조건
    (,개시 위치)
)

지정한 조건(정규 표현)에 일치하는 부분의 최초의 값을 돌려줍니다.임의에, 검색을 개시하는 개시 위치를 지정하는 것도 가능합니다

REGEXP_SUBSTR

REGEXP_SUBSTR(
    문자열 또는 열명,
    조건
)

지정한 정규 표현에 일치하는 부분 문자열을 뽑아내 결과적으로 돌려줍니다

REGEXP_REPLACE

REGEXP_REPLACE(
    열명 또는 문자열,
    조건,
    치환 문자열
)

지정한 정규 표현에 일치하는 부분을 지정한 다른 문자열로 치환합니다. 복잡한 치환/검색 조작을 가능하게 합니다

표1 정규 표현을 사용하는 함수

 

 

1.REGEXP_LIKE함수

^^^^^^^^^^^^^^^^^^^^^^^^^

정규 표현을 사용해 애매한 조건 검색을 실시할 경우에 이용합니다.

 

構文

 REGEXP_LIKE(열명,조건)

 

 

 

SQL> SELECT * FROM TEST_REGEXP;

COL1
----------
ABCDE01234
01234ABCDE
abcde01234
01234abcde

SQL> SELECT * FROM TEST_REGEXP WHERE REGEXP_LIKE(COL1,'[0-9][A-Z]');

COL1
----------
01234ABCDE

SQL> SELECT * FROM TEST_REGEXP WHERE REGEXP_LIKE(COL1,'[0-9][a-z]');

COL1
----------
01234abcde

리스트1 REGEXP_LIKE 함수를 사용한 fuzzy reference

 

조금 익숙해 지면 이하와 같은 체크 사용도 가능합니다.

 

SQL> ALTER TABLE QA_MASTER ADD CONSTRAINT QA_NO_CHK CHECK
  2  (REGEXP_LIKE(QA_NO,
  3  '^([[:alpha:]]{2}-[[:digit:]]{2}-[[:digit:]]{4})$'));

Table altered.

SQL> INSERT INTO QA_MASTER VALUES('QA-01-0001');

1 row created.

SQL> INSERT INTO QA_MASTER VALUES('00-01-0001');
INSERT INTO QA_MASTER VALUES('00-01-0001')
*
ERROR at line 1:
ORA-02290: check constraint (ORAORA.QA_NO_CHK) violated

리스트2 Q/A관리 마스터에 QA번호를 등록할 때의 서식의 체크

 

이와 같이 허용된 데이터형식만을 체크할수 있습니다.

 

2.REGEXP_INSTR함수

^^^^^^^^^^^^^^^^^^^^^^^^^^

지정한 정규 표현에 일치하는 부분이 몇번째 문자인지를 돌려줍니다.

 

構文
 REGEXP_INSTR(문자열 또는 열명, 조건)

 

 

 

SQL> SELECT COL1,REGEXP_INSTR(COL1,'[0-9]') ,
  2  REGEXP_INSTR(COL1,'%') from TEST_REGEXP;

COL1       REGEXP_INSTR(COL1,'[0-9]') REGEXP_INSTR(COL1,'%')
---------- -------------------------- ----------------------
ABCDE01234                          6                      0
01234ABCDE                          1                      0
@|=)(9&%$#                          6                      8
あいうえ3                           5                      0

6 rows selected.

리스트3 REGEXP_INSTR를 사용한 지정 문자의 위치 검색

 

N번째 문자 이후의 숫자 출력은......

 

SQL> SELECT COL1,REGEXP_INSTR(COL1,'[0-9]',4) FROM TEST_REGEXP;

COL1       REGEXP_INSTR(COL1,'[0-9]',4)
---------- ----------------------------
ABCDE01234                            6
01234ABCDE                            4
abcde01234                            6
01234abcde                            4

리스트4 N번째 문자 이후의 숫자 출력

 

 

3.REGEXP_SUBSTR함수

^^^^^^^^^^^^^^^^^^^^^^^^^^^ 

지정한 정규 표현에 일치하는 부분을 뽑아내 결과적으로 돌려줍니다.

 

構文
 REGEXP_SUBSTR(문자열 또는 열명, 조건)

 

 


SQL> SELECT COL1,REGEXP_SUBSTR(COL1,'[C-Z]+') FROM TEST_REGEXP;

COL1       REGEXP_SUBSTR(COL1,'[C-Z]')
---------- ---------------------------
ABCDE01234 CDE
01234ABCDE CDE
abcde01234
01234abcde

리스트 5 지정한 문자열을 선택


SQL> SELECT COL1,REGEXP_SUBSTR(COL1,'[C-Z]') FROM TEST_REGEXP;

COL1       REGEXP_SUBSTR(COL1,'[C-Z]')
---------- ---------------------------
ABCDE01234 C
01234ABCDE C
abcde01234
01234abcde

리스트 6 해당하는 1 문자만을 선택

 

 

4.REGEXP_REPLACE함수

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

지정한 정규 표현에 일치하는 부분을 지정한 다른 문자열로 교체합니다.

 

構文
 REGEXP_REPLACE(열명 또는 문자열, 조건, 치환 문자열)

 

 


SQL> SELECT COL1,REGEXP_REPLACE(COL1,'[0-2]+','*') FROM TEST_REGEXP;

COL1       REGEXP_REPLACE(COL1,'[0-2]+','*')
---------- --------------------------------------------------
ABCDE01234 ABCDE*34
01234ABCDE *34ABCDE
abcde01234 abcde*34
01234abcde *34abcde

리스트 7 지정한 부분의 문자를 다른 문자로 치환


 

정규 표현의 다양한 활용 방법


SQL문으로 정규 표현이 가능하게 되어서 지금까지는 약간의 세공(PL/SQL나 조건식의 나열)이 필요함 작업을 간단하게 실현될 수 있게 되었습니다. 예를 들면 전자 메일이나 우편번호(해외등에서는 영문자도 포함된다) 격납열에의 검색·입력 체크도 간단합니다.그 외  데이타베이스 이행시에 문제가 되는 외자의 검출, 불필요한 공백 문자의 검출, 중복어의 출현의 식별 및 문자열의 해석·치환 등에도 위력을 발휘합니다.

 

이상과 같이, Oracle10g의 SQL 조작에 관한 추가된 기능입니다만, 알고 있으면 편리하겠져.. 

(계속 연제됩니다.)

반응형
반응형

레코드가 있으면 UPDATE하고 없으면 INSERT해라 였는데,
오라클9i에서 새로 추가된 MERGE INTO 구문을 사용하면

대략 구문은 아래와 같습니다.
pl/sql환경에서는 위와 같이 사용해도 되지만,
sql을 꼭 사용해야한다면 이 방법이 낫겠네요.

[SYNTAX]

MERGE INTO 테이블 A                        -- update 또는 insert할 테이블
USING (테이블명 | SUBQUERY | 뷰)  B  -- 비교 대상
ON(A와 B의 조인식)                             -- 대상테이블과 비교테이블의 조인식
WHEN MATCHED THEN                       -- on절에서 일치하는 로우가 있다면
    UPDATE SET = , , ....                       -- 업데이트하고,
WHEN NOT MATCHED THEN                -- 일치하는 로우가 없다면
    INSERT INTO(컬럼명)                       -- insert를
    VALUES(값, 값, ...)                           -- 이 값으로 넣어라.

f_u1:
   merge into tb_result a
        using dual             b
           on ( a.plt_no = '$in_plt_no' and
                a.srt_id = '$in_srt_id' )
   when matched then
      update set srt_qty     = srt_qty + to_number('$in_srt_qty'),
                 fin_chgr_id = '$in_user_id',
                 fin_chg_dtm = to_char(sysdate, 'yyyymmddhh24miss')
   when not matched then
      insert ( plt_no       , srt_id            , proj_no         , blk_no            ,
               sass_no      , prcd_sass_no      , ptlst_no        , pcs_gb            ,
               stype        , srt_qty           , uom_wgt         , bom_org_cmpo      ,
               io_gb        , req_gb            , ptlst_stat      , req_ser           ,
               lug_gb       , mpart_plt_no      , newprod_qty     , reprod_qty        ,
               imprv_yn     , plt_incd_yn       , fs_srt_usr_id   , fs_srt_dtm        ,
               fs_inpr_id )
      values ( '$in_plt_no' , '$in_srt_id'      , '$in_proj_no'   , '$in_blk_no'      ,
               '$in_sass_no', '$in_prcd_sass_no', '$in_ptlst_no'  , '$in_pcs_gb'      ,
               '$in_stype'  , to_number('$in_srt_qty'), to_number('$in_uom_wgt'), '$in_bom_org_cmpo',
               '$in_io_gb'  , '$in_req_gb'      , 'C'             , to_number('$in_req_ser'),
               '$in_lug_gb' , '$in_mpart_plt_no', to_number('$in_new_srt_qty'), to_number('$in_re_srt_qty'),
               'N'          , 'Y'               , '$in_user_id'   , to_char(sysdate, 'yyyymmddhh24miss'),
               '$in_user_id' )
   ;

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

f_u2:
   declare cursor csr1 is
      select a.lug_gb       as lug_gb  ,
             a.ptlst_no     as lug_type,
             '$in_bizcls'   as bizcls  ,
             sum(a.srt_qty) as srt_qty
      from   tb_result a
      where  a.plt_no = '$in_plt_no'
      group  by a.lug_gb, a.ptlst_no
      $in_semicolon

      begin
         for rec1 in csr1 loop
            update tb_result
            set    stk_qty     = stk_qty - rec1.srt_qty * decode('$in_out_gb', 'O', 1, -1),
                   fin_chgr_id = '$in_user_id',
                   fin_chg_dtm = to_char(sysdate, 'yyyymmddhh24miss')
            where  lug_gb      = rec1.lug_gb
            and    lug_type    = rec1.lug_type
            and    bizcls      = rec1.bizcls
            $in_semicolon

            if sql%notfound then
               insert into tb_stk
                         ( lug_gb    ,
                           lug_type  ,
                           bizcls    ,
                           stk_qty   ,
                           fs_inpr_id    )
                  values ( rec1.lug_gb  ,
                           rec1.lug_type,
                           rec1.bizcls  ,
                           rec1.srt_qty * decode('$in_out_gb', 'O', -1, 1),
                           '$in_user_id' )
               $in_semicolon
            end if $in_semicolon
         end loop $in_semicolon
      end $in_semicolon
   ;

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

테이터를 넣어야할 테이블에

값이 이미 있으면 Update

값이 없으면 Insert

 

MERGE INTO table_name alias                               --테이블 명만 올수 있음(셀렉트 쿼리 No)
          USING (table|view|subquery) alias                --일반적으로 쓰는 쿼리 Ok
          ON (join condition)                                        --where 절이라고 생각하면됨(조건에 서브 OK)
          WHEN MATCHED THEN                              --데이터 중복건이 있는경우 Update
                       UPDATE SET col1 = val1[, col2 = val2…]
          WHEN NOT MATCHED THEN                      -- 중복건이 없는 경우 처리 Insert
                       INSERT (컬럼리스트) VALUES (값들....);

ex)

   MERGE INTO CRCD_WF_CARD A            
   USING DUAL                           
      ON ( A.WF_NO = ? AND A.CRD_NO =? )
    WHEN MATCHED    THEN                
         UPDATE  SET                    
                 A.CRD_TYPE       =?    
               , A.FML_SSN        =?    
               , A.FMLHG_NM       =?    
               , A.FMLENG_NM      =?    
               , A.OCRD_NO        =?    
               , A.DSN_CD         =?    
               , A.DSN_NM         =?    
               , A.BRD_CD         =?    
               , A.CRD_GRD        =?    
               , A.INTGLMT_AMT    =?    
               , A.FML_STLACCT_NO =?    
               , A.CRD_ISSUE_DT   =?    
    WHEN NOT MATCHED THEN               
         INSERT (                       
                 A.WF_NO                
               , A.CRD_NO               
               , A.CRD_TYPE             
               , A.FML_SSN              
               , A.FMLHG_NM             
               , A.FMLENG_NM            
               , A.OCRD_NO              
               , A.DSN_CD               
               , A.DSN_NM               
               , A.BRD_CD               
               , A.CRD_GRD              
               , A.INTGLMT_AMT          
               , A.FML_STLACCT_NO       
               , A.CRD_ISSUE_DT         
                                        
       ) VALUES ( ?, ?, ?, ?, ?, ?, ?,  
                  ?, ?, ?, ?, ?, ?, ?  )

-------------------------------------------------------

ex2)

    MERGE INTO TC_CUSTAGENT A
   USING (SELECT BUSI_CODE, CUST_CODE, CHPE_NAME, CUST_PHNB, CUST_FANU
                FROM TB_ESTMAST
                WHERE BUSI_CODE = '___parameter___'

                     AND CUST_CODE = '____parameter___') B
    ON (A.BUSI_CODE = B.BUSI_CODE
           AND A.AFON_COMP = B.CUST_CODE
           AND A.SEQU_NUMB = (SELECT MAX(SEQU_NUMB)
                                            FROM TC_CUSTAGENT
                                            WHERE BUSI_CODE = A.BUSI_CODE
                                                  AND AFON_COMP = A.AFON_COMP))
   WHEN MATCHED THEN
         UPDATE
         SET  A.CHPE_NAME = B.CHPE_NAME
                ,A.CABL_PHNB = B.CUST_PHNB
                ,A.FAXM_NUMB = B.CUST_FANU
    WHEN NOT MATCHED THEN
         INSERT (  A.AFON_COMP
                       ,A.CHPE_NAME
                       ,A.CABL_PHNB
                       ,A.FAXM_NUMB     
                     )
         VALUES (  B.CUST_CODE
                        ,B.CHPE_NAME      
                        ,B.CUST_PHNB
                        ,B.CUST_FANU    
                      );


>>>>>>>>>>>>>>>>
 
 MERGE INTO
실제 적용하면서 발견한 문제점 (ORACLE 9.2.0.3.0 에서)

 

9.2.0.4.0 버젼에선 아래와 같은 문법으로도 MERGE INTO 가 정상적으로 동작하였다.

 

MERGE INTO POPULAR_KEYWORD
USING DUAL B
ON (FIX_YN = 'Y' AND CATEGORY = 'ALL' AND RANK = '1')
WHEN MATCHED THEN
  UPDATE SET REG_DATE = SYSDATE
WHEN NOT MATCHED THEN
  INSERT (CATEGORY,KEYWORD,RANK, COUNT, REG_DATE)
      VALUES ('ALL','TEST22','1','100',SYSDATE)

 

즉, ON 절에서 값이 NULL 이더라도 WHEN NOT MATCHED THEN 절을 정상적으로 수행하였는데

 

이상하게 다른서버(9.2.0.3.0) 에선 ON절의 값이 NULL 이면 정상적인 루틴을 밟지 못하드라..

즉, INSERT 문을 수행하지 못했다.

[ 0 rows Merged ]

 

그래서 아래와 같이 USING절에서 NULL값이 리턴하지 않게 변경해주고

ON 절에서 A 와 B 를 JOIN 해주니까 정상적으로 동작한다.

 

MERGE INTO POPULAR_KEYWORD2 A
      USING (SELECT 'ALL' CATEGORY, '4' RANK, 'Y' FIX_YN FROM   DUAL) B
      ON (A.CATEGORY = B.CATEGORY AND A.RANK = B.RANK AND A.FIX_YN = B.FIX_YN)
      WHEN MATCHED THEN
        UPDATE SET REG_DATE = SYSDATE
      WHEN NOT MATCHED THEN
        INSERT (CATEGORY,KEYWORD,RANK, COUNT, REG_DATE)
            VALUES ('ALL','TEST22','4','100',SYSDATE)

[ 1 rows Merged ]

 

결론 ==> USING 다음의 SELECT 문의 결과 데이타는 반드시 존재하여야 한다 (NULL 불가).

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

9i이상에서는 데이타가 존재할 경우 갱신 없으면 등록하는 명령어로

MERGE INTO ~ USING ~ ON ~ WHEN ~ 명령어가 있습니다.


 

MERGE INTO oc_whslr_trd_rslt A
USING (
SELECT std_yymm, cust_nbr, whlsr_cust_nbr, sol_tp_cd, sol_cd,chnn_rt,

src_tp_cd,org_cd, emp_nbr,sell_amt, qty
FROM oc_temp_whslr_trd_rslt
) B
ON (

A.std_yymm = B.std_yymm AND

A.cust_nbr = B.cust_nbr AND

A.whlsr_cust_nbr = B.whlsr_cust_nbr AND

A.sol_cd = B.sol_cd AND

A.sol_tp_cd = B.sol_tp_cd AND

A.chnn_rt = B.chnn_rt
)
WHEN MATCHED THEN

UPDATE SET A.sell_amt = A.sell_amt + B.sell_amt,
A.qty = A.qty + B.qty
WHEN NOT MATCHED THEN
INSERT (
A.std_yymm,
A.cust_nbr,
A.whlsr_cust_nbr,
A.sol_cd,
A.sol_tp_cd,
A.chnn_rt,
A.src_tp_cd,
A.org_cd,
A.emp_nbr,
A.sell_amt,
A.qty,
A.drtn_amt,
A.drtn_qty,
A.last_chng_emp,
A.last_chng_dt )
VALUES (
B.std_yymm,
B.cust_nbr,
B.whlsr_cust_nbr,
B.sol_cd,
B.sol_tp_cd,
B.chnn_rt,
B.src_tp_cd,
B.org_cd,
B.emp_nbr,
B.sell_amt,
B.qty,
0,
0,
'CRMSP',
TO_CHAR(sysdate,'YYYYMMDD')
);

 

 

 

MERGE into KAC_PERSON a USING
(select user_id, OPER_FG, VARDATA, NUMDATA from KAC_PERSON
where user_id='57CCF7ADE63F3AC1' AND OPER_FG = 'MAIL_CAPACITY') b
ON (a.user_id=b.user_id and a.OPER_FG=b.OPER_FG)
WHEN MATCHED THEN UPDATE set a.NUMDATA = 15
WHEN NOT MATCHED THEN INSERT (a.user_id,a.OPER_FG,a.VARDATA,a.NUMDATA)
VALUES ('57CCF7ADE63F3AC1','MAIL_CAPACITY','mail',50)

 

CREATE TABLE KAC_PERSON
(
  USER_ID    CHAR(16) NOT NULL,
  OPER_FG    VARCHAR2(20) NOT NULL,
  VARDATA    VARCHAR2(30),
  NUMDATA    NUMBER(4),
  CONSTRAINT PK_KAC_PERSON PRIMARY KEY (USER_ID, OPER_FG)
);

>>>>>>>>>>>>>>>>>>>>>>>>>


MERGE INTO tb_target a
USING (
   select proj_no, spl_no, tag_no, msch_actv, instl_plt_no, wk_ord_dt
   from   tb_source
   where  lot_no  = 'AJ'
   and    proj_no = '1697'
   ) b
ON (   a.proj_no = b.proj_no
   and a.spl_no  = b.spl_no
   and a.tag_no  = b.tag_no)
WHEN MATCHED THEN
   update
   set    a.mk_fndt   = b.wk_ord_dt,
          a.matdlv_dt = b.wk_ord_dt,
          a.gr_dt     = b.wk_ord_dt,
          a.stk_dt    = b.wk_ord_dt,
          a.gi_dt     = b.wk_ord_dt
WHEN NOT MATCHED THEN
   insert(a.proj_no, a.spl_no, a.tag_no, a.msch_actv, a.instl_plt_no,
          a.mk_fndt, a.matdlv_dt, a.gr_dt, a.stk_dt, a.gi_dt)
   values(b.proj_no, b.spl_no, b.tag_no, b.msch_actv, b.instl_plt_no,
          b.wk_ord_dt,b.wk_ord_dt,b.wk_ord_dt,b.wk_ord_dt,b.wk_ord_dt)

반응형

+ Recent posts