ORACLE/ADMIN2011. 1. 30. 22:48
반응형

OS : Linux Fedora 9

Oracle Release 11.2.0.1.0

오라클 11g(Release 11.2.0.1.0)를 성공적으로 설치하였음에도 불구하고 서버가 설치된 머신 에서는 sqlplus등의 Tool로 정상적으로 접속이 이루어졌지만, 원격으로 접속하는 경우 ORA-12514오류가 발생하면서 접속이 이루어 지지 않아 다음의 내용을 오라클 서버의 listener.ora를 수정함으로 해결 되었다. 수정이 된 이후에는 오라클 리스너를 새로 시작해야 한다.

 

대상파일 : /Oracle/Database/oracle/product/11.2.0/dbhome/network/admin/listener.ora

 

수정 前

 +1 LISTENER =

 +2   (DESCRIPTION_LIST =

 +3     (DESCRIPTION =

 +4       (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))

 +5       (ADDRESS = (PROTOCOL = TCP)

(HOST = localhost.localdomain)(PORT = 1521))

 +6     )

 +7   )

 +8

 +9 ADR_BASE_LISTENER = /Oracle/Database/oracle

 

수정 後(붉은색 부분이 추가된 부분)

 +1 SID_LIST_LISTENER =

 +2 (SID_LIST =

 +3     (SID_DESC =

 +4         (SID_NAME = PLSExtProc)

 +5         (ORACLE_HOME = /Oracle/Database/oracle/product/11.2.0/dbhome)

 +6         (PROGRAM = extproc)

 +7     )

 +8     (SID_DESC =

 +9         (ORACLE_HOME = /Oracle/Database/oracle/product/11.2.0/dbhome)

+10         (SID_NAME = mjs)

+11     )

+12 )

+13

+14

+15 LISTENER =

+16   (DESCRIPTION_LIST =

+17     (DESCRIPTION =

+18       (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))

+19       (ADDRESS = (PROTOCOL = TCP)

(HOST = localhost.localdomain)(PORT = 1521))

+20     )

+21   )

+22

+23 ADR_BASE_LISTENER = /Oracle/Database/oracle

 

반응형
Posted by [PineTree]
ORACLE/SCRIPT2010. 11. 24. 14:43
반응형
## for unix
$ _DATE=`date +%y%m%d`
$ _DIR=/data/exp
$ exp asd/asd@asd file = ${_DIR}/file_name_${_DATE}.dmp

## for window
c:\> exp asd/asd@asd file = file_name_"%DATE%".dmp

#################################################################################
crontab 설정 파일

#!/bin/bash
datetime=$(date +%Y%m%d)

exp mediasp/mediasp file="/backup/phoenix/phoenixdb_$datetime.dmp" log="/backup/phoenix/phoenixdb_$datetime.log" full=y direct=y


반응형

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

ORACLE Session Statistics 쿼리  (0) 2011.12.21
ORACLE 중복 데이터 확인  (0) 2010.05.28
OPTEIMIZING ORACLE OPTIMIZER 스크립트 모음  (0) 2010.04.28
ORACLE INDEX,TABLE정보 조회  (0) 2010.04.28
과도한 I/O 유발 쿼리 찾기  (0) 2010.04.15
Posted by [PineTree]
ORACLE/ADMIN2010. 11. 23. 18:12
반응형

-Analyze는 Serial Statistics Gathering 기능만 있는 반면, dbms_stats는 Parallel Gathering기능이있다.

-Analyze는 파티션의 통계정보를 각 파티션 테이블과 인덱스에 대해서 수집하고,

Golbal Statistics는 파티션 정보를 가지고 계산하므로, 부정확할 수 있다.

그러므로 파티션 또는 서브파티션이 있는 객체에는 DBMS_STATS을 사용 하여야 한다.

-DBMS_STATS는 전체 클러스터에 대해서는 통계정보를 수집하지 않는다. 그러므로 Analyze를 사용한다.

-DBMS_STATS는 CBO와 관련된 통계정보만을 수집한다.

즉, 테이블의EMPTY_BLOCKS, AVG_SPACE, CHAIN_CNT 등은 수집되지 않는다.

-DBMS_STATS는 사용자가 지정한 통계정보 테이블에 수집된 통계정보를 저장할수있고,

딕셔너리로 각 컬럼, 테이블, 인덱스, 스키마등을 반영 할 수 있다.

-DBMS_STATS는 IMPORT/EXPORT 기능 및 추가적인 기능이 많다.

이 기능을 이용하여 운영 DB의 통계정보를 개발장비의 통계정보로

복사할 수 있으므로 개발장비의 팰린을 운영장비와 같게 만들 수 있다.(메뉴얼 참조)

 

Optimizer statistics 생성은 시간과 자원이 많이 드는 작업입니다.

Optimizer를 지원하기 위한 통계 생성 작업에서 Optimizer가 Cost 계산에 고려하지 않는

정보를 만들기 위해서 시간과 자언을 사용할 필요는 없을 것입니다.

 

그래서 아래 내용이 피룡하다면 여전히 analyze 명령을 사용해야 합니다.

 

ANALYZE 명령

 

analyze 명령은 DBMS_STATS 패키지를 사용하기 전에 사용했던 명령으로, 유사한 통계자료를 수집하는데

사용된다. DBMS_STATS 패키지가 통계 자료 수집에 더 우수하기 때문에 오라클은 패키지의 사용을 권장하지만,

DBMS_STATS 패키지로 수ㅡ집할 수 없는 통계 자료는 다음과 같습니다.

 

- VALIDATE 또는 LIST CHAINED ROWS 절의 사용

- 통계 자료 예측시 행의 샘플 개수

- 프리리스트 블록 관련 정보와 같은 옵티마이저에 의해 사용되지 않는 통계 자료 수집.

 

SQL> ANALYZE TABLE table_name VALIDATE STRUCTURE;

 

test방법

 

1세션과 2세션으로 구분하여 test하면된다.

 

 1 session t1 analyze

 2 session t2 dbms_stats

SQL> create table t1 (c1 number, c2 varchar2(10), c3 varchar2(10));

테이블이 생성되었습니다.

SQL> exec p('select * from user_tables where table_name = ''T1'' ')
---------------------------------------------------
TABLE_NAME                    : T1
TABLESPACE_NAME               : SYSTEM
CLUSTER_NAME                  :
IOT_NAME                      :
STATUS                        : VALID
PCT_FREE                      : 10
PCT_USED                      : 40
INI_TRANS                     : 1
MAX_TRANS                     : 255
INITIAL_EXTENT                : 65536
NEXT_EXTENT                   :
MIN_EXTENTS                   : 1
MAX_EXTENTS                   : 2147483645
PCT_INCREASE                  :
FREELISTS                     : 1
FREELIST_GROUPS               : 1
LOGGING                       : YES
BACKED_UP                     : N
NUM_ROWS                      :
BLOCKS                        :
EMPTY_BLOCKS                  :
AVG_SPACE                     :
CHAIN_CNT                     :
AVG_ROW_LEN                   :
AVG_SPACE_FREELIST_BLOCKS     :
NUM_FREELIST_BLOCKS           :
DEGREE                        :          1
INSTANCES                     :          1
CACHE                         :     N
TABLE_LOCK                    : ENABLED
SAMPLE_SIZE                   :
LAST_ANALYZED                 :
PARTITIONED                   : NO
IOT_TYPE                      :
TEMPORARY                     : N
SECONDARY                     : N
NESTED                        : NO
BUFFER_POOL                   : DEFAULT
ROW_MOVEMENT                  : DISABLED
GLOBAL_STATS                  : NO
USER_STATS                    : NO
DURATION                      :
SKIP_CORRUPT                  : DISABLED
MONITORING                    : YES
CLUSTER_OWNER                 :
DEPENDENCIES                  : DISABLED
COMPRESSION                   : DISABLED
DROPPED                       : NO
---------------------------------------------------

PL/SQL procedure successfully completed.
SQL> analyze table t1 compute statistics;

Table analyzed.

SQL> exec p('select * from user_tables where table_name = ''T1'' ')
---------------------------------------------------
TABLE_NAME                    : T1
TABLESPACE_NAME               : SYSTEM
CLUSTER_NAME                  :
IOT_NAME                      :
STATUS                        : VALID
PCT_FREE                      : 10
PCT_USED                      : 40
INI_TRANS                     : 1
MAX_TRANS                     : 255
INITIAL_EXTENT                : 65536
NEXT_EXTENT                   :
MIN_EXTENTS                   : 1
MAX_EXTENTS                   : 2147483645
PCT_INCREASE                  :
FREELISTS                     : 1
FREELIST_GROUPS               : 1
LOGGING                       : YES
BACKED_UP                     : N
NUM_ROWS                      : 0
BLOCKS                        : 0
EMPTY_BLOCKS                  : 7
AVG_SPACE                     : 0
CHAIN_CNT                     : 0
AVG_ROW_LEN                   : 0
AVG_SPACE_FREELIST_BLOCKS     : 0
NUM_FREELIST_BLOCKS           : 0
DEGREE                        :          1
INSTANCES                     :          1
CACHE                         :     N
TABLE_LOCK                    : ENABLED
SAMPLE_SIZE                   : 0
LAST_ANALYZED                 : 23-NOV-2010 16:27:57
PARTITIONED                   : NO
IOT_TYPE                      :
TEMPORARY                     : N
SECONDARY                     : N
NESTED                        : NO
BUFFER_POOL                   : DEFAULT
ROW_MOVEMENT                  : DISABLED
GLOBAL_STATS                  : NO
USER_STATS                    : NO
DURATION                      :
SKIP_CORRUPT                  : DISABLED
MONITORING                    : YES
CLUSTER_OWNER                 :
DEPENDENCIES                  : DISABLED
COMPRESSION                   : DISABLED
DROPPED                       : NO
---------------------------------------------------

 

PL/SQL procedure successfully completed.

SQL> insert into t1 select level, 'test1', 'test2' from dual connect by level <= 1000;

1000 rows created.
SQL> analyze table t1 compute statistics;

Table analyzed.

SQL> exec p('select * from user_tables where table_name = ''T1'' ')
---------------------------------------------------
TABLE_NAME                    : T1
TABLESPACE_NAME               : SYSTEM
CLUSTER_NAME                  :
IOT_NAME                      :
STATUS                        : VALID
PCT_FREE                      : 10
PCT_USED                      : 40
INI_TRANS                     : 1
MAX_TRANS                     : 255
INITIAL_EXTENT                : 65536
NEXT_EXTENT                   :
MIN_EXTENTS                   : 1
MAX_EXTENTS                   : 2147483645
PCT_INCREASE                  :
FREELISTS                     : 1
FREELIST_GROUPS               : 1
LOGGING                       : YES
BACKED_UP                     : N
NUM_ROWS                      : 1000
BLOCKS                        : 3
EMPTY_BLOCKS                  : 4
AVG_SPACE                     : 1114
CHAIN_CNT                     : 0
AVG_ROW_LEN                   : 19
AVG_SPACE_FREELIST_BLOCKS     : 1698
NUM_FREELIST_BLOCKS           : 1
DEGREE                        :          1
INSTANCES                     :          1
CACHE                         :     N
TABLE_LOCK                    : ENABLED
SAMPLE_SIZE                   : 1000
LAST_ANALYZED                 : 23-NOV-2010 16:30:07
PARTITIONED                   : NO
IOT_TYPE                      :
TEMPORARY                     : N
SECONDARY                     : N
NESTED                        : NO
BUFFER_POOL                   : DEFAULT
ROW_MOVEMENT                  : DISABLED
GLOBAL_STATS                  : NO
USER_STATS                    : NO
DURATION                      :
SKIP_CORRUPT                  : DISABLED
MONITORING                    : YES
CLUSTER_OWNER                 :
DEPENDENCIES                  : DISABLED
COMPRESSION                   : DISABLED
DROPPED                       : NO
---------------------------------------------------

PL/SQL procedure successfully completed.

 SQL> create table t2(c1 number, c2 varchar2(10), c3 varchar2(10));

Table created.

SQL> exec p('select * from user_tables where table_name = ''T2'' ')
---------------------------------------------------
TABLE_NAME                    : T2
TABLESPACE_NAME               : SYSTEM
CLUSTER_NAME                  :
IOT_NAME                      :
STATUS                        : VALID
PCT_FREE                      : 10
PCT_USED                      : 40
INI_TRANS                     : 1
MAX_TRANS                     : 255
INITIAL_EXTENT                : 65536
NEXT_EXTENT                   :
MIN_EXTENTS                   : 1
MAX_EXTENTS                   : 2147483645
PCT_INCREASE                  :
FREELISTS                     : 1
FREELIST_GROUPS               : 1
LOGGING                       : YES
BACKED_UP                     : N
NUM_ROWS                      :
BLOCKS                        :
EMPTY_BLOCKS                  :
AVG_SPACE                     :
CHAIN_CNT                     :
AVG_ROW_LEN                   :
AVG_SPACE_FREELIST_BLOCKS     :
NUM_FREELIST_BLOCKS           :
DEGREE                        :          1
INSTANCES                     :          1
CACHE                         :     N
TABLE_LOCK                    : ENABLED
SAMPLE_SIZE                   :
LAST_ANALYZED                 :
PARTITIONED                   : NO
IOT_TYPE                      :
TEMPORARY                     : N
SECONDARY                     : N
NESTED                        : NO
BUFFER_POOL                   : DEFAULT
ROW_MOVEMENT                  : DISABLED
GLOBAL_STATS                  : NO
USER_STATS                    : NO
DURATION                      :
SKIP_CORRUPT                  : DISABLED
MONITORING                    : YES
CLUSTER_OWNER                 :
DEPENDENCIES                  : DISABLED
COMPRESSION                   : DISABLED
DROPPED                       : NO
---------------------------------------------------


PL/SQL procedure successfully completed.

SQL> exec dbms_stats.gather_table_stats(user,'T2')

PL/SQL procedure successfully completed.

SQL> exec p('select * from user_tables where table_name = ''T2'' ')
---------------------------------------------------
TABLE_NAME                    : T2
TABLESPACE_NAME               : SYSTEM
CLUSTER_NAME                  :
IOT_NAME                      :
STATUS                        : VALID
PCT_FREE                      : 10
PCT_USED                      : 40
INI_TRANS                     : 1
MAX_TRANS                     : 255
INITIAL_EXTENT                : 65536
NEXT_EXTENT                   :
MIN_EXTENTS                   : 1
MAX_EXTENTS                   : 2147483645
PCT_INCREASE                  :
FREELISTS                     : 1
FREELIST_GROUPS               : 1
LOGGING                       : YES
BACKED_UP                     : N
NUM_ROWS                      : 0
BLOCKS                        : 0
EMPTY_BLOCKS                  : 0
AVG_SPACE                     : 0
CHAIN_CNT                     : 0
AVG_ROW_LEN                   : 0
AVG_SPACE_FREELIST_BLOCKS     : 0
NUM_FREELIST_BLOCKS           : 0
DEGREE                        :          1
INSTANCES                     :          1
CACHE                         :     N
TABLE_LOCK                    : ENABLED
SAMPLE_SIZE                   : 0
LAST_ANALYZED                 : 23-NOV-2010 16:28:36
PARTITIONED                   : NO
IOT_TYPE                      :
TEMPORARY                     : N
SECONDARY                     : N
NESTED                        : NO
BUFFER_POOL                   : DEFAULT
ROW_MOVEMENT                  : DISABLED
GLOBAL_STATS                  : YES
USER_STATS                    : NO
DURATION                      :
SKIP_CORRUPT                  : DISABLED
MONITORING                    : YES
CLUSTER_OWNER                 :
DEPENDENCIES                  : DISABLED
COMPRESSION                   : DISABLED
DROPPED                       : NO
---------------------------------------------------

PL/SQL procedure successfully completed.

SQL> insert into t2 select level, 'test1', 'test2' from dual connect by level <= 1000;

1000 rows created.

SQL> exec dbms_stats.gather_table_stats(user,'T2')

PL/SQL procedure successfully completed.

SQL> exec p('select * from user_tables where table_name = ''T2'' ')
---------------------------------------------------
TABLE_NAME                    : T2
TABLESPACE_NAME               : SYSTEM
CLUSTER_NAME                  :
IOT_NAME                      :
STATUS                        : VALID
PCT_FREE                      : 10
PCT_USED                      : 40
INI_TRANS                     : 1
MAX_TRANS                     : 255
INITIAL_EXTENT                : 65536
NEXT_EXTENT                   :
MIN_EXTENTS                   : 1
MAX_EXTENTS                   : 2147483645
PCT_INCREASE                  :
FREELISTS                     : 1
FREELIST_GROUPS               : 1
LOGGING                       : YES
BACKED_UP                     : N
NUM_ROWS                      : 1000
BLOCKS                        : 3
EMPTY_BLOCKS                  : 0
AVG_SPACE                     : 0
CHAIN_CNT                     : 0
AVG_ROW_LEN                   : 15
AVG_SPACE_FREELIST_BLOCKS     : 0
NUM_FREELIST_BLOCKS           : 0
DEGREE                        :          1
INSTANCES                     :          1
CACHE                         :     N
TABLE_LOCK                    : ENABLED
SAMPLE_SIZE                   : 1000
LAST_ANALYZED                 : 23-NOV-2010 16:30:39
PARTITIONED                   : NO
IOT_TYPE                      :
TEMPORARY                     : N
SECONDARY                     : N
NESTED                        : NO
BUFFER_POOL                   : DEFAULT
ROW_MOVEMENT                  : DISABLED
GLOBAL_STATS                  : YES
USER_STATS                    : NO
DURATION                      :
SKIP_CORRUPT                  : DISABLED
MONITORING                    : YES
CLUSTER_OWNER                 :
DEPENDENCIES                  : DISABLED
COMPRESSION                   : DISABLED
DROPPED                       : NO
---------------------------------------------------

PL/SQL procedure successfully completed.

 

 위 결과와 같이 analyze 와 dbms_stats의 차이는

 EMPTY_BLOCKS, AVG_SPACE, CHAIN_CNT, AVG_SPACE_FREELIST_BLOCKS, NUM_FREELIST_BLOCKS들을

수집하느냐 안하느냐를 볼수있다.

그리고 AVG_ROW_LEN값이 틀려지고 AVG_ROW_LEN yes냐 no의 차이도있다.

 


반응형
Posted by [PineTree]
ORACLE/ADMIN2010. 11. 23. 18:00
반응형
출 처 : http://blog.naver.com/clearsn?Redirect=Log&logNo=90100665253


++히스토그램 생성 방법++

exec dbms_stats.gather_table_stats(user_name, 'table_name', method_opt=>'option');

 

user_name : 유저명

table_name : table이름

option :

for all columns size 1 : 모든 column 에 대해서 histogram을 수집하지 않는다.

- Oracle이 Data 분포를 고려하여 Bucket Size를 계산한다.

for all columns size auto : column이 predicate로 사용된적이 있는 경우에만 histogram을 수집

for all columns size skewonly :predicate로 사용된적이 없어도 histogram을 수집

-

for all indexed columns size skewonly : index가 존재하는 컬럼에 대해서만 histogram을 수집

for columns c1 size 5 c2 size skewonly : 개별 column 별로 bucket size 를 할당

for all hidden columns size skewonly : function based index 에 의해 생성된 hidden column에 대한 histogram을 수집

[출처] Histogram 생성 방법.|작성자 dnflfl



반응형
Posted by [PineTree]
ORACLE/ADMIN2010. 11. 8. 17:50
반응형

문자셋과 인코딩의 정의

  • 문자셋 (charset, Character Set)
하나의 언어권에서 사용하는 언어를 표현하기 위한 모든 문자(활자)의 모임을 문자셋(charater set)이라고 한다. 다시 말하면 우리가 얘기하는 언어를 책으로 출판할 때 필요한 문자(활자)를 모두 모은 것이라고 생각하면 된다. 추가적으로 부호와 공백 등과 같은 특수 문자도 문자셋에 포함된다.
영어의 경우 알파벳 대소문자와 특수 문자 등으로 간단하게 문자셋을 구성할 수 있지만 한글의 경우 출판에서 가,나,다 등으로 출판함으로 훨씬 다양한 문자셋을 가지고, 또한 한자를 병행해서 사용함으로 문자셋의 범위는 더욱 넓어진다.
  • 추상적인 글자 셋은 여러 개의 인코딩을 가질 수 있다.
  • MIME 문자셋은 IANA에서 정의하며 인터넷 및 XML 파일에서 사용한다.
  • 인코딩 (encoding)
인코딩은 문자셋을 컴퓨터가 이해할 수 있는 바이트와 매핑하는 규칙이다. 예를 들면 ASCII Code에서 A,B,C 등은 문자셋이고 A는 코드 65, B는 코드 66 등 바이트 순서와 매핑한 것이 인코딩이다. 따라서 문자셋을 어떻게 매핑하느냐에 따라 하나의 문자셋이 다양한 인코딩을 가질 수 있다.
  • 추상적인 문자셋을 구체적인 bit-stream으로 표기하는 방법
  • 여러가지 문자셋을 동시에 표시할 수 있다.
  • 대부분의 인코딩에서는 대소문자를 구분하지 않는다.
  • 대한민국 문자셋(charater set)에서 가장 많이 사용하는 인코딩은 "UTF-8", "KSC5601", "ISO-8859-1" 이다.
  • 문자셋(인코딩)의 예
  • 한글 : 8bit KSC5601 (8bit EUC-KR, 7bit ISO-2022-KR, ISO-2022-Int)
  • 영문 : KSC5636, US-ASCII (둘 간의 차이는 화페 단위 뿐)
  • 한글+영문 : KSC5861 (EUC-KR), KSC5636 + KSC5601를 모두 포함한다.
  • 유니코드 : 4byte Unicode < ISO-10646 UCS (ISO-8859-1, UTF-8, UTF-16)

문자셋과 인코딩은 동일한 명칭을 가질 수 있어 서로 혼용하여 사용되는 경우가 많다.
EUC-KR은 원래 유닉스용 표준이었는데 인터넷으로 확장되어 사용된다.
KSC5601은 인터넷에서 원활한 한글(완성형) 사용을 위하여 정의된 표준이다.
EUC (Extended UNIX Code), UTF (UCS Transformation format)

기본 인코딩

  • Windows : 시스템 언어와 관련된 코드 페이지를 따름
    • 영문 Windows는 CP1252 인코딩을 사용
    • 한글 Windows는 MS949 인코딩을 사용
  • Unix : LANG 환경 변수로 지정된 로케일에 해당하는 인코딩
    • Solaris는 LANG 환경 변수가 ko, ko_KR일 경우 EUC-KR 인코딩을 사용
    • HP는 LANG 환경 변수가 ko_KR, ko_KR.eucKR일 경우 EUC-KR 인코딩을 사용
    • Unix에서 locale -a 명령을 사용하여 LANG 환경 변수에 지정 가능한 문자셋을 확인할 수 있다.
  • HTML : ISO-8859-1와 ISO-10646
  • XML : UTF-8
  • 웹 브라우져 : 내부적으로 모두 유니코드로 처리를 한다.
  • HTTP/1.0 : ISO-8859-1
  • HTTP (URL,URI) : US-ASCII, %hexadecimal_code, JavaScript escape() 함수 사용
  • Java : 유니코드 2.0
  • 직렬화된 Java Class : UTF-8
  • J2EE : ISO-8859-1
  • Oracle : UTF-8 (AL32UTF8), 한국에서는 KSC5601 (KO16KSC5601)




다양한 환경에서 인코딩 설정

웹 브라우져 설정

  1. "도구 -> 인터넷 옵션 -> 언어" 메뉴를 선택한다.
  2. 영어[en]와 한국어[ko]를 추가하고 원하는 언어를 가장 상단에 위치한다.

JVM 설정

  • 일반적으로 LANG 환경 변수를 설정해 주면 자동으로 설정이 된다.
locale -a                               Solaria unix 명령어로 지원 가능한 encoding을 확인한다.
env LANG ko csh에서 Encoding을 설정한다. (KSC5601, EUC-KR)
LANG=ko ksh에서 Encoding을 설정한다. (KSC5601, EUC-KR)
  • JVM 옵션 설정 (UTF-8, ISO-8859-1, KSC5601)
-Dfile.encoding=8859_1                  필수 항목
-Dfile.client.encoding=8859_1
-Dclient.encoding.override=8859_1 JVM 버전에 따라 (사용안함)
  • JSP를 사용하여 JVM 옵션 확인 (encoding.jsp)
file.encoding = <%= System.getProperty("file.encoding") %><br>
file.client.encoding = <%= System.getProperty("file.client.encoding") %><br>
client.encoding.override = <%= System.getProperty("client.encoding.override") %><br>

HTML 설정

HTML 파일을 UTF-8로 만들어 저장한다.

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

XML 설정

XML 파일을 UTF-8로 만들어 저장한다.

<?xml version="1.0" encoding="UTF-8" ?>

JSP 설정

JSP 파일을 UTF-8로 만들어 저장한다.

<%@ page pageEncoding="UTF-8" %>
<%@ page contentType="text/html;charset=UTF-8" %>

Servlet 설정

HTTP 요청의 인코딩 지정

request.setCharacterEncoding("UTF-8");

HTTP 응답의 인코딩 지정

response.setContentType("text/html; charset=UTF-8");

web.xml 설정

<mime-mapping>
<extension>html</extension>
<mime-type>text/html;charset=UTF-8</mime-type>
</mime-mapping>

Default Oracle Database 문자셋

  • Default Oracle Database 문자셋 : UTF-8 (AL32UTF8), 한국에서는 KSC5601 (KO16KSC5601)
  • AL32UTF8, KO16KSC5601 (KSC5601), WE8ISO8859P1 (8859_1)
  • Default Oracle Database 문자셋 확인 방법
sqlplus system/manager

select parameter || ' : ' || value parameter_value
from NLS_DATABASE_PARAMETERS
where parameter = 'NLS_CHARACTERSET'
or parameter = 'NLS_NCHAR_CHARACTERSET';

select name || ' : ' || substr(value$, 1, 40) parameter_value
from sys.props$
where name = 'NLS_CHARACTERSET';

select parameter || ' : ' || value parameter_value
from NLS_INSTANCE_PARAMETERS, V$NLS_PARAMETERS, NLS_SESSION_PARAMETERS;
  • Oracle Database 문자셋 변경 방법
환경 변수 또는 %ORACLE_HOME%/dbs/init[SID].ora 을 설정한다.
NLS_LANG='American_America.Ko16ksc5601'
ORA_NLS33='$ORACLE_HOME/ocommon/nls/admin/data'
NLS_DATE_FORMAT='YYYY-MM-DD'
  • DriverManager에서 문자셋 설정 방법
java.util.Properties props = new java.util.Properties();
props.put("charSet", "KSC5601" );
DriverManager.getConnection(dbUrl, props);
반응형
Posted by [PineTree]
ORACLE/ADMIN2010. 10. 22. 10:08
반응형

 

PCTFREE
럭내에 행을 수정하거나 업데이트 발생 있는 행의 크기 증가에 대비하여 예약된 공간. 초기 입력시에는 공간을 제외하고 입력된다. PCTFREE 부족하면 데이터 수정이나 업데이트 행이전(ROW MIGRATION) 발생하게 된다.

PCTUSED
새로운 행이 블록에 추가되기 전에 행데이터와 오버헤드에 대해 사용될수 있는 블록의 최소 퍼센트이다. , 기존의 데이터가 수정이나 삭제등으로 PCTUSED보다 값이 작아지면 블록에 한하여 입력이 가능하다. 

INITRANS
블록에 동시에 엑세스 가능한 트렉젝션의 초기수를 나타낸다. (기본값 : 1)
INITRANS
낮게 설정하는 경우는 테이블이 크고 테이블에 엑세스하는 사용자의 수가 적을 경우이고, 높게 설정하는 경우는 엑세스하는 사용자가 많을 경우이다. 

MAXTRANS
동시에 엑세스 가능한 트렉젝션의 최대값으로 INITRANS 상대적 개념이다. (기본값 : 255)
MAXTRNAS
너무 낮은 경우 트렉젝션을 초과한 사용자가 엑세스한 경우 앞의 사용자가 커밋이나 롤백하기 까지 기다려야하는 경우가 발생한다. 

FREELIST
테이블로 데이터를 INSERT 하기 위하여 미리 할당하는 프리 블록의 리스트 수를 지정. 

NOCACHE
NOCACHE
옵션은 'DB 캐시를 사용하지 않겠다' 파라미터로서 이것을 CACHE 지정하면 한번에 20개의 값을 캐시한다. 기본값은 NOCACHE이다.

ex)
USING INDEX 
TABLESPACE TSI_BIO01 PCTFREE 20
STORAGE ( INITIAL 16384 NEXT 471556096 PCTINCREASE 80 ))
TABLESPACE TSD_BIO01
PCTFREE 20
PCTUSED 80
INITRANS 1
MAXTRANS 255
STORAGE ( 
INITIAL 1064960
NEXT 1048576
PCTINCREASE 0
MINEXTENTS 1
MAXEXTENTS 2147483645
FREELISTS 1 FREELIST GROUPS 1 )
NOCACHE; 


PCTFREE, PCTUSED 필요한가?
ROW CHANNING
현상과 ROW MIGRATION 현상에 대하여 알아야 한다.
ROW CHANNING
DB_BLOCK_SIZE보다 너무 데이터가 들어왔을 경우 인접한 다른 블록까지 데이터가 넘어가는 것을 말한다.
이런 경우, 만약에 데이터의 특징을 가진다면 LOB TYPE으로 다른 TABLESPACE 저장하는 것이 옳다.
지만 ROW CHANNING 일반적인 현상이다. 물론 9I 경우엔 파라미터에 DB_?K_CACHE_SIZE 주고 ?K CREATE TABLESPACE ~~ BLOCKSIZE ?K; 정하면 DB_BLOCK_SIZE 보다 BLOCK_SIZE 가지는 TABLESPACE 만들고 안에 데이터를 넣는다면 ROW CHANNING 방지할 있다.
경우 ROW CHANNING 어쩔 없는 현상이다.
하지만, ROW MIGRATION 막아야 하는 사항이다.
이것을 예를 들어 보자.

a. A
라는 테이블에 10번째 값을 INSERT
b.
이어서 11번째 값을 INSERT
c.
그런데 10번째 값을 유저가 UPDATE시켰는데, UPDATE 데이터가 예전의 데이터보다 크기가 크다!
d.
이때 DB BLOCK 11번째 때문에 여유공간이 없어서 다른 BLOCK으로 해당 데이터를 이동을 하게 된다.

이런 경우가 자주 일어나는 것은 좋지 않다. 그래서 PCTFREE, PCTUSED이라는 개념이 생긴 것이다.

PCTFREE 10, PCTUSED 40
이라고 한다면?
초기 블록에 데이터가 들어가다가 PCTUSED 40% 넘겼다. 그래도 계속해서 INSERT 한다.
그러다가 PCTFREE 10% 데이터가 90%넘게 채워질 경우에는 이상 데이터가 들어가지 않고 블록에 여유공간을 남겨둔다.
FILE HEADER
에서 FREELIST라는 것을 관리하는데 이것은 SEGMENT 들어갈 빈공간이 있는지를 확인하는 것이다.
상의 경우에서 데이터 기록량이 90% 넘기면 (, PCTFREE공간이 10% 이하가 된다면) 블록을 FREELIST에서 제거를 하고 블록은 INSERT 중단하고 다른 FREELIST 등록된 블록에 데이터를 넣을 것이다.
나중에 데이터가 UPDATE 경우를 블록의 10%만큼 미리 준비하는 것이다.

만약, 블록의 데이터마저 줄어든다면?
90%
보다 줄어들 경우 계속해서 0까지 줄어든다면, 블록을 FREELIST에서 삭제된 상황이니 이상 INSERT 되지 않는다.
경우를 대비하여 어떤 기준을 마련해두어야 한다.
PCTUSED
이렇게 BLOCK 데이터가 없어질 경우의 최소값을 말한다.
, 최소한 PCTUSED 만큼은 데이터가 들어가서 DB BLOCK 낭비를 최소화 하자 것이다.
이것이 PCTUSED 필요한 이유이다.

90%
이상으로 데이터를 채운 블록에서 데이터가 삭제되어 90% 미만로 떨어지게 되었다.
PCTFREE값이 10% 보다 여유공간이 생기는 것이다. 하지만 오라클은 PCTFREE 10%보다 여유공간이 생겨도 FREELIST 블록을 추가하지 않는다. , 데이터가 점점 줄다가 60%정도의 데이터가 되더라도 FREELIST 등록하지 않는다.

PCTUSED
보다 적어지는 상황이 생길 경우는?
PCTUSED 40%
보다 적어지는 상황이 생길 경우가 되어서야 비로소 데이터를 넣을 있도록 FREELIST 등록한다. 
하지만 9I에서는 PCTFREE, PCTUSED 방법은 권하지 않는다.
SEGMENT SPACE MANAGEMENT AUTO
절을 넣어서 AUTO 관리하도록 한다.

AUTO방식
AUTO
방식의 경우는 PCTFREE 관리한다.
블록을 25% 4개로 나눠 관리하는 방식이다. AUTO 쓰면 데이터 블록의 낭비를 막고 ROW MIGRATION 해결해준다. 수동은 권하지 않음!!!

STORAGE ( INITIAL 16384 NEXT 471556096 PCTINCREASE 80 ))
이상에서 STORAGE 절은 EXTENT할당 방식을 말한다.
두가지 방식이 있는데, 8I에서는 DEFAULT EXTENT 할당할 때에 DICTIONARY EXTENT MANAGED TABLESPACE 사용했다.
물론 이때도 LOCALLY EXTENT MANAGED TABLESPACE 만들 수는 있다.
9I
에서는 LOCALLY EXTENT MANAGED TABLESPACE DEFAULT값이다.

이상의 차이는 EXTENT 할당하는 방식에 따른다.
DICTIONARY EXTENT TABLESPACE
생성할 경우엔 테이블스페이스의 EXTENT 할당시에 정보를 SYSTEM TABLESPAE BASE TABLE에서 가져온다.
지만, EXTENT할당을 여기저기서 하다보니 SYSTEM TABLESPACE 조회해서 EXTENT 어디를 할당하면 것인지 확인하고 EXTENT 할당 할당정보를 SYSTEM TABLESPACE 저장한다. (병목현상 심함!)

그러나, LOCALLY EXTENT MANAGE TABLESPACE 경우엔 그렇지 않다.
SYSTEM TABLESPACE
BASE TABLE에서 EXTENT 여유공간 정보를 가져오는 것이 아니라 해당 데이터파일 헤더에 직접 BITMAP BLOCK으로 저장된다.
그래서 EXTENT할당시에 SYSTEM TABLESPACE에서 찾아서 할당하는 것이 아니라 자신이 속한 테이터파일의 헤더의 BITMAP BLOCK에서 찾겠죠. (경합현상이 거의 발생하지 않는다!)
오라클사에서는 DICTIONARY 방식을 사용하지 말고 LOCALLY TABLESPACE 사용하도록 권한다.

9I
에서 SYSTEM TABLESPACE LOCALLY TABLESPACE 경우, 일반 TABLESPACE생성시 DEFAULT STORAGE(DICTIONARY 방식) 사용되지 않는다. (에러발생!)
하지만 SYSTEM TABLESPACE DICTIONARY TABLESPACE 경우엔 DEFAULT STORAGE(DICTIONARY 방식) 통해서 CREATE TABLESPACE 사용할 있다.

만약, CREATE TABLE 절에 STORAGE 준다면 어떻게 될까?
이런 경우 EXTENET MANAGEMENT LOCAL 방식의 경우엔 질문사항인 STORAGE 절을 주게 되면 모두 무시된다. , TABLESPACE에서 정한 UNIFORM SIZE대로(DEFAULT라면 1M 만큼) EXTENT 할당한다. 

SYSTEM TABLESPACE
DICTIONARY TABLESAPCE라면?
경우에는 일반 TABLESPACE 만들 경우에 DEFAULT STORAGE절을 지정할 있다. 하지만, CREATE TABLE 명령에서 질문과 같이 STORAGE절을 주게 되면 TABLESPACE 설정은 모두 무시되고 CREATE TABLE 설정을 따른다.

STORAGE ( INITIAL 16384 NEXT 471556096 PCTINCREASE 80 ))
무엇을 뜻하는가?
SYSTEM TABLESPACE
LOCALLY EXTENT MANAGED TABLESPACE에서는 이상의 절을 이용하는 것이 불가능하므로, DICTIONARY EXTENT MANAGED TABLESAPCE라고 있다. 또한 TABLESPACE DICTIONARY EXTENT MANAGED TABLESAPCE이다. 

CREATE TABLE TEST ( ID NUMBER ) STORAGE STORAGE ( INITIAL 16384 NEXT 471556096 PCTINCREASE 80 ));
기에 테이블에 EXTENT 16384 바이트만큼을 미리 할당한다. EXTENT안에 DB BLOCK들에 데이터가 들어갔는데 데이터가 많이 들어가서 모두 데이터가 찼을 경우 새로운 EXTENT 할당 한다. 이때에 NEXT 만큼을 할당하는 것이다.
PCTINCREASE 80
다음의 경우, 80% 만큼 크게 늘어난다는 것이다. 

EXTENT1
에서는 16384
EXTENT2
에서는 16384 + 471556096
EXTENT3
에서는 (16384 + 471556096 + 471556096 ) * ( 1 + 0.8 )

이렇게 PCTINCREASE 쓰게 되면 쓸데없이 한꺼번에 EXTENT 할당받으므로 다른 TABLE에서 만큼 공간을 쓰지 못하게 된다. 따라서, PCTINCREASE 쓰면 안된다!
그리고, DICTIONARY방식은 쓰지 말고 LOCALLY 방식으로 UNIFORM SIZE 지정하라!
UNIFORM SIZE
대부분의 경우 10M 정도로 UNIQUE하게 주면 적당하다. (너무 크면 안됨!)

여러 테이블의 데이터가 들어가는데 너무 많은 EXTENT 생겨서 다른 테이블의 데이터와 섞이지 않나?
SMON
이라는 오라클 프로세스가 알아서 하므로, 고려할 없다.


최종 정리

PCTFREE 20
: UPDATE
위해서 DB BLOCK 최소한 20% 정도의 공간을 남겨두겠다.

PCTUSED 80
: PCTFREE
인한 공간낭비를 막기 위해서 최소한 80% 만큼의 데이터는 넣겠다.

INITRANS 1
: SEGMENT
트랜젝션이 최소 한개 이상 걸릴 있도록 한다.

MAXTRANS 255
: SEGMENT
트랜잭션이 최대 255개까지 걸릴 있도록 한다.

INITIAL 1064960
:
초기의 EXTENT 크기

NEXT 1048576
:
초기 EXTENT할당후 EXTENT 부족할 경우 다음 EXTENT 할당 크기

PCTINCREASE 0
: 0%
늘이겠다. (무시됨!)

MINEXTENTS 1
:
최소한의 EXTENT 할당하겠다.(INITIAL 10K 인데 MINEXTENTS 2 라면? TABLE 생성하면서 20K 미리 할당. 20부터 시작.)

MAXEXTENTS 2147483645
:
최대한의 EXTENT. (현재값은 데이터가 커지면 문제있다)

FREELISTS 1 FREELIST GROUPS 1
:
데이터블록의 SEGMENT관리에서 한개 FREELIST에서 FREE BLOCK 찾고 데이터를 넣는 것에 많은 트랜잭션이 처리를 경우 성능이 나빠지게 된다. 그래서 FREELIST 경우에 여러개가 있으면 분산이 가능하다. FREELIST GROUP FREELIST 몇개를 FREELIST GROUP으로 사용한다는 의미이다.

EXTENT : 보조 기억 장치에서, 파일이 연속적으로 기록되어 있는 일련의 블록
 

반응형
Posted by [PineTree]
ORACLE/ADMIN2010. 10. 7. 17:37
반응형
제품 : SQL*NET

작성날짜 : 2002-11-29

(9I) 다른 장비에 있는 REMOTE LISTENER 설정하여 로컬 데이타베이스 사용하기
==================================================

PURPOSE


아래의 test는 9i 데이터베이스에서 remote machine에 있는 listener을 사용하는 방법에
대해 다룬다.


Explanation & Example



데이터베이스가 운영중인 machine 은 'krint-5' 이며
listener을 띄울 machine은 'krind2'이다.


< remote machine(krind2)에서의 작업 >

1. remote machine(krind2)에 listener.ora을 만든다.
아래와 같이 SID_LIST_LISTENER 절은 필요치 않으며 LISTENER절만 있으면 된다.
만약 remote machine에도 데이타베이스가 존재한다면 그 데이타베이스를 나타내는
SID_LIST_LISTENER 절을 포함해도 상관이 없다.

ex)

LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = krind2)(PORT = 1901))
)
)
)

2. 위와 같이 setup한후 listener를 시작한다.

lsnrctl start

< local machine(krint-5)에서의 작업 >

1. local machine에서 init<SID>.ora에 remote listener을 등록한다.
(만약 spfile을 사용한다면 그에 맞게 수정한다)

*.dispatchers="(protocol=tcp)(disp=4)"
*.remote_listener="(address=(protocol=tcp)(host=krind2)(port=1901))"

( 참고 : listener port응 어떤것을 사용해도 무방하다)

2. 위와 같이 setup이 끝나면 데이타베이스를 새로 시작한다.

< remote machine(krind2)에서의 확인 >

1. remote machine에서 listener.log을 확인한다.

29-NOV-2002 19:31:08 * service_register * ORA920 * 0
29-NOV-2002 19:31:17 * service_update * ORA920 * 0
29-NOV-2002 19:31:20 * service_update * ORA920 * 0

ORA920 이 instance_name 이다.

2. "lsnrctl service" 확인한다.

/home/ora901/product/901/network/admin> lsnrctl ser

LSNRCTL for Linux: Version 9.0.1.4.0 - Production on 29-NOV-2002 19:32:18

Copyright (c) 1991, 2001, Oracle Corporation. All rights reserved.

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=krind2)(PORT=1901)))
Services Summary...
Service "ORA920" has 1 instance(s).
Instance "ORA920", status READY, has 5 handler(s) for this service...
Handler(s):
"DEDICATED" established:0 refused:0 state:ready
REMOTE SERVER
(ADDRESS=(PROTOCOL=TCP)(HOST=)(PORT=1521))
"D006" established:0 refused:0 current:0 max:1002 state:ready
DISPATCHER <machine: krint-5, pid: 5506>
(ADDRESS=(PROTOCOL=tcp)(HOST=krint-5.kr.oracle.com)(PORT=41748))
"D005" established:0 refused:0 current:0 max:1002 state:ready
DISPATCHER <machine: krint-5, pid: 5504>
(ADDRESS=(PROTOCOL=tcp)(HOST=krint-5.kr.oracle.com)(PORT=41747))
"D004" established:0 refused:0 current:0 max:1002 state:ready
DISPATCHER <machine: krint-5, pid: 5502>
(ADDRESS=(PROTOCOL=tcp)(HOST=krint-5.kr.oracle.com)(PORT=41746))
"D003" established:0 refused:0 current:0 max:1002 state:ready
DISPATCHER <machine: krint-5, pid: 5500>
(ADDRESS=(PROTOCOL=tcp)(HOST=krint-5.kr.oracle.com)(PORT=41745))
The command completed successfully

< Client에서 접속해 보기 >

1. 연결을 위해 tnsnames.ora 을 수정한다.

r_list.world =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = krind2)(PORT = 1901))
)
(CONNECT_DATA =
(SERVICE_NAME = ORA920)
)
)

2. sqlplus등으로 점속을 해 본다.
remote machine에 있는 listener.log을 보면 remote listener을 이용하여
local machine에 있는 데이타베이스에 접속이 잘 되었음을 알수 있다.

29-NOV-2002 19:36:48 * (CONNECT_DATA=(SID=ORA920)(CID=(PROGRAM=PLUS33W.EXE)(HOST
=jooyeon-kr)(USER=jooyeon))) * (ADDRESS=(PROTOCOL=tcp)(HOST=152.69.41.120)(PORT=
2865)) * establish * ORA920 * 0

( 참고 : 반드시 MTS을 사용해야 하며 그렇지 않다면 작동하지 않는다.)

RELATED DOCUMENTS


<Note:206550.1>
반응형
Posted by [PineTree]
ORACLE/10G2010. 8. 16. 15:59
반응형


출처 : http://blog.naver.com/darkturtle?Redirect=Log&logNo=50014575918


누가 그랬던가, DBA 가 가장 빛나는 시간 중 하나가 Data 복구라고..

쉽고 강력한 FlashBack에 간단히 Review

원문 : Reviewed by Oracle Certified Master Korea Community
( http://www.ocmkorea.com http://cafe.daum.net/oraclemanager )
A REWIND BUTTON FOR ORACLE 10G DATABASE
– FLASHBACK BEST PRACTICES

 

 

FlashBack 관련 정리

Flashback technology is one of the key features within Oracle
database products in reducing the mean time to recover (MTTR) from database failures
caused by logical data corruption or human errors.


1. Flashback Query [ rely on the Automatic Undo Management ]
 This feature lets you specify a target time or SCN in the past and then run
 queries against your database to view any data at that time
 using the AS OF clause of the SELECT statement. Can be used to recover
 from any unwanted changes like an erroneous update to a table.
 
2.Flashbackup Version Query  [ rely on the Automatic Undo Management ]                    
 Provides a mechanism to review the changed versions of all rows made
 to the database in a specified time interval. With this feature, You
 can also retrieve metadata about the differing versions of the rows,
 including start time, end time, operation, and transaction ID of the
 transaction that created the version. Therefore, you can recover lost data
 values and audit any changes made to the tables queried.
 
3. Flashback Transaction Query  [ rely on the Automatic Undo Management ]
 Lets you view changes made by a single transaction, or by all the transactions
 during a period of time.
 
4. Flashback Table [ rely on the Automatic Undo Management ]
 This feature can return a table to its state at a previous point in time.
 You can easily restore table data while the database is online, undoing
 changes only to the specified table.
 
5. Flashback Drop [ uses a mechnism of recycle bin ]
 Undo the effects of a DROP TABLE statement.
 
6. Flashback Database [
 This is a new and more efficient strategy for doing point-in-time recovery.
 It likes a “rewind button” embedded within the database to let you rewind
 your database to a point in time and correct any problems caused
 by human errors, data corruption or any other logical data errors. 
--------------------------------------------------------------------------------
  Flashback <================= Data Buffer ====================> Redo log
  Buffer    Not every change                               Every change          Buffer
    |                                                                                              |
    |-------------------|                             |----------------------|  
                       RVWR                            LGWR 
                        |                                    |
                Flashback Logs            Redo Logs
- Flashback area : flashback database logs, archived redo logs, and RMAN backups
- Flashback Database log is another new concept. It is the old versions of changed
  blocks of the database, and these flashback logs are located at Flash Recovery area.
- Flashback buffer is a new cache within SGA. It is used for caching the snapshot 
  of changed data blocks. 
- RVWR (Recovery Writer) is a new background process, which is started
  whenever Flashback Database is enabled.
--------------------------------------------------------------------------------
!! Automatic Undo Management ...
Used primarily for such purposes as providing read
consistency for SQL queries and rolling back transactions, these undo segments
should contain sufficient information required to reconstruct data as it stood
at a past time and examine the record of changes since that past time.
 
ARCHITECTURE AND CONSIDERATION FOR ORACLE 10G FLASHBACK
 
 You may ask, how far can you flash back into the past?
of course, this depends on how much UNDO information retained in the
database's UNDO segments, and is bounded by the time frame specified
by the UNDO_RETENTION initialization parameter.

- UNDO_MANAGEMENT : setting to AUTO, which ensures that the database is using
 an undo tablespace.
- UNDO_TABLESPACE : Define which undo tablespace to use. The size of
 UNDO tablespace is another key factor for flashback features, that determine
 how much information retains within the UNDO space.
 For Oracle Real Application Cluster (RAC) environment, each instance has its own UNDO space.
- UNDO_RETENTION : setting this initialization parameter to a value that causes
 UNDO to be kept for how far you can flashback in time.
 By default, this setting is 900 seconds (15 minutes)
- RETENTION GUARANTEE - This is a statement clause used for UNDO tablespace
 to guarantee that unexpired undo will not be overwritten.

SCENARIO 1: FLASHBACK QUERY
On Monday afternoon, a junior DBA helped to perform emergency maintenance
for a developer against the EMPLOYEE table, inadvertently deleted the data
for employee ‘PETER’ from the table. After careful researches, the senior DBA
knew the approximate time at which this had occurred.

## Check Sysdate
SCOTT@TEST_T.WORLD>select sysdate from dual ;
SYSDATE
-------------------
2007.02.21 18:58:47

## Delete MILLER ( NO PETER T_T )
SCOTT@TEST_T.WORLD>delete emp where ename ='MILLER';
1 row deleted.

## Commit !!
SCOTT@TEST_T.WORLD>commit ;
Commit complete.

## Check Sysdate
SCOTT@TEST_T.WORLD>select sysdate from dual ;

SYSDATE
-------------------
2007.02.21 18:59:03

SCOTT@TEST_T.WORLD>  select * from emp as of timestamp
                     to_timestamp('2007/02/21 185803','YYYY/MM/DD HH24MISS')
                     where ename ='MILLER' ;


     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
      7934 MILLER     CLERK           7782 1982.01.23 00:00:00       1300                    10
==> Delete 된 Row 가 보인다. [ 맞는지 체크 ! ]

# Delete row 복구
SCOTT@TEST_T.WORLD>insert into emp ( select * from emp as of timestamp
  2   to_timestamp('2007/02/21 185803','YYYY/MM/DD HH24MISS') where ename ='MILLER') ;

1 row created.

# Commit
SCOTT@TEST_T.WORLD>commit ;
Commit complete.

## 복구 Data 확인
SCOTT@TEST_T.WORLD>select * from emp where ename ='MILLER' ;

     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
      7934 MILLER     CLERK           7782 1982.01.23 00:00:00       1300                    10
 
SCENARIO 2: FLASHBACK VERSION QUERY
You are the DBA for a Peoplesoft HR system. On 9:00 AM Monday morning,
HR manager sent you an urgent email regarding some abnormal changes of
your employee table data during weekend. Yor are asked to retrieve the
information about the transactions that changed the rows of employee table.

This is an common scenario for data auditing. Oracle 10g Flashback Version Query
provides a easy way for data auditing.

It can retrieve all committed versions of the rows that exist or ever existed
between the time the query was issued and a point in time in the past,
as long as those versions are still available within the UNDO tablespace's rollback segments.
A new pseudocolumn VERSIONS_XID is introduced as a transaction identifier of
the corresponding version of a row, and the transactionVERSIONS clause is
used to retrieve all of the versions of the rows that exist between two points
in time or two SCNs. The rows returned by Flashback Versions Query present
a history of the rows across transctions. It is worth to mention that
Flashback Versions Query only return comitted transactions.

# Attention [  UNDO_RETENTION By default, this setting is 900 seconds (15 minutes) ]
# Transaction Log 발생
SCOTT@TEST_T.WORLD>delete emp where ename in ( 'SMITH','ALLEN','WARD') ;

3 rows deleted.

SCOTT@TEST_T.WORLD>commit ;

Commit complete.
SCOTT@TEST_T.WORLD>select sysdate from dual ;

SYSDATE
-------------------
2007.02.21 19:20:13


# Check Logs
   select versions_xid, versions_operation, ename from emp
   versions between timestamp to_timestamp('2007.02.21 19:10:47','YYYY.MM.DD HH24:MI:SS') and
   to_timestamp('2007.02.21 19:20:00','YYYY.MM.DD HH24:MI:SS')
   where versions_operation is not null ;
  
VERSIONS_XID     V ENAME
---------------- - ----------
000400170002F837 D WARD
000400170002F837 D ALLEN
000400170002F837 D SMITH

when using Flashback Version Query, there exists following limitations:
- VERSIONS BETWEEN clause cannot be used for External Tables,
  Temporary Tables, and Fixed Tables.
- VERSIONS BETWEEN clause cannot be used for views
- VERSIONS BETWEEN cannot produce versions of rows across DDL statements
  that changes the table structures
- VERSIONS BETWEEN can be used in the subqueries of DDL and DML statements
- ORA-30052 error if not appropriate UNDO_RENTION

SCENARIO 3: FLASHBACK TRANSACTION QUERY
According the Scenario 2, you have found some changes happening on you employee table.
These transactions include the UPDATE, DELETE, and INSERT. However,
you are required to know what operations have been made on the transaction level,
how to undo the changes back to its before immages, and finally use the undo DML
to recover the data. This is an urgent need for HR department.

FLASHBACK_TRANSACTION_QUERY is a view within Oracle 10g database to determine
all the necessary SQL information that can be used to undo the chnages
that were made by a specific transaction during a specific time period.

{ This note contains error information about an "Oracle Server"
  error number. It may contain additional support notes as
  described in Note 22080.1 }

  1  select versions_xid, ename from emp versions between timestamp
  2  to_timestamp('2007.02.21 19:28:47','YYYY.MM.DD HH24:MI:SS') and
  3  to_timestamp('2007.02.21 19:38:00','YYYY.MM.DD HH24:MI:SS')
  4* where ename ='WARD'
SCOTT@TEST_T.WORLD> select versions_xid, ename from emp versions between timestamp
                    to_timestamp('2007.02.21 19:28:47','YYYY.MM.DD HH24:MI:SS') and    
                    to_timestamp('2007.02.21 19:38:00','YYYY.MM.DD HH24:MI:SS')
                    where ename ='WARD' ;           *
ERROR at line 1:
ORA-08186: invalid timestamp specified

Error:   ORA-08186  (ORA-8186)
Text:   invalid timestamp specified
---------------------------------------------------------------------------
Cause: as stated above
Action: enter a valid timestamp
==> 상기 원인은 19:38:00 분이 아직 되지 않은 시점이었다.
SCOTT@TEST_T.WORLD>  select versions_xid, ename from emp versions between timestamp
 to_timestamp('2007.02.21 19:20:47','YYYY.MM.DD HH24:MI:SS') and
 to_timestamp('2007.02.21 19:34:00','YYYY.MM.DD HH24:MI:SS')
 where ename ='WARD'
 /
no rows selected

## 조금 이상하다. 다시 함 체크 해보자
## 복구할 Data 발생
SCOTT@TEST_T.WORLD>delete emp where empno in ( 7782, 7788,7839 ) ;
3 rows deleted.
SCOTT@TEST_T.WORLD>commit ;
Commit complete.
## Check Sysdate
SCOTT@TEST_T.WORLD>select sysdate from dual ;
SYSDATE
--------------------
2007.02.21 19:53:44

# 시간으로
     select * from emp versions between timestamp
     to_timestamp('2007.02.21 19:45:00','YYYY.MM.DD HH24:MI:SS') and
     to_timestamp('2007.02.21 19:55:44','YYYY.MM.DD HH24:MI:SS')


#  원본 테이블과  차이 보기 및 백업 데이타 [ 시간에 쫒기는거라 ㅡ_ㅡ; ]
     create table differ_emp as
     select * from emp versions between timestamp
     to_timestamp('2007.02.21 19:45:00','YYYY.MM.DD HH24:MI:SS') and
     to_timestamp('2007.02.21 19:55:44','YYYY.MM.DD HH24:MI:SS')
     minus
     select * from emp

# 데이타 확인     
 select * from differ_emp
# 원본에 없는 데이타만 입력 
insert into emp select * from differ_emp minus select * from emp

## XID 값을 통해서 Undo 구하는 방식으로는 where in 절의 3 row 에 대한
   undo 문이 return 되지 않고, 한 Transaction 내의 첫번째 row 만 recovery
   가능한 undo_sql 문이 구해진다.... ㅜ_ㅜ

       
### Test 하기 까탈스러워서 undo_retention 을 늘려주다
### live 환경에서 어떻게 가는지 체크 해보자

SYS@TEST_T.WORLD>show parameter undo

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS1
SYS@TEST_T.WORLD>alter system set undo_retention = 30000 ;
System altered.

SYS@TEST_T.WORLD>show parameter undo

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     30000
undo_tablespace                      string      UNDOTBS1


SCENARIO 4: FLASHBACK TABLE
The current time is 12 PM on April 2, 2005. Your HR user run an erroneous DML
while trying to fix the employee tablel data, some of the
employee data lost. You are required to recover the data ASAP.

Like flaskback query, to implement Flashback Table feature, you have
to configure UNDO_TABLESPACE and UNDO_RETENTION to guanantee enough space
to hold undo data, and time for retaining undo data. Appropriate undo
information can control how far back in time a table can be repaired using this feature.

Because Flashback Table feature does
not preserve the original row IDs, it is necessary to enable row movement
on the impacted tables first before performing the flashback table.


SCOTT@TEST_T.WORLD>select sysdate from dual ;

SYSDATE
-------------------
2007.02.21 19:53:44

SCOTT@TEST_T.WORLD>select * from emp ;

     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
      7844 TURNER     SALESMAN        7698 1981.09.08 00:00:00       1500          0         30
      7876 ADAMS      CLERK           7788 1983.01.12 00:00:00       1100                    20
      7900 JAMES      CLERK           7698 1981.12.03 00:00:00        950                    30
      7902 FORD       ANALYST         7566 1981.12.03 00:00:00       3000                    20
      7934 MILLER     CLERK           7782 1982.01.23 00:00:00       1300                    10

# 복구할 시간 체크
SCOTT@TEST_T.WORLD>select sysdate from dual ;
SYSDATE
-------------------
2007.02.21 20:38:26

# 복구할 데이타 삭제
SCOTT@TEST_T.WORLD>delete emp ;
5 rows deleted.

SCOTT@TEST_T.WORLD>commit ;
Commit complete.

# 장애 타이밍 체크
SCOTT@TEST_T.WORLD>select sysdate from dual ;
SYSDATE
-------------------
2007.02.21 20:38:46

# 복구 가능하도록 Table 설정 변경
SCOTT@TEST_T.WORLD>alter table emp enable row movement ;
Table altered.

# flashback table ...
SCOTT@TEST_T.WORLD>flashback table emp to timestamp to_timestamp('2007.02.21 20:38:26','YYYY.MM.DD HH24:MI:SS') ;
Flashback complete.

# 복구 확인
SCOTT@TEST_T.WORLD>select * from emp ;

     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
      7844 TURNER     SALESMAN        7698 1981.09.08 00:00:00       1500          0         30
      7876 ADAMS      CLERK           7788 1983.01.12 00:00:00       1100                    20
      7900 JAMES      CLERK           7698 1981.12.03 00:00:00        950                    30
      7902 FORD       ANALYST         7566 1981.12.03 00:00:00       3000                    20
      7934 MILLER     CLERK           7782 1982.01.23 00:00:00       1300                    10

## 장애 시점으로 다시 복구(delete 된 상황으로 원복)
SCOTT@TEST_T.WORLD>flashback table emp to timestamp to_timestamp('2007.02.21 20:38:46','YYYY.MM.DD HH24:MI:SS') ;
Flashback complete.

## Delete 상황 다시 체크
SCOTT@TEST_T.WORLD>select * from emp ;
no rows selected

## 다시 문제 발생 이전 시점으로 복구
SCOTT@TEST_T.WORLD>flashback table emp to timestamp to_timestamp('2007.02.21 20:38:26','YYYY.MM.DD HH24:MI:SS') ;
Flashback complete.

## 복구 상황 체크
SCOTT@TEST_T.WORLD>select * from emp ;

     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
      7934 MILLER     CLERK           7782 1982.01.23 00:00:00       1300                    10
      7844 TURNER     SALESMAN        7698 1981.09.08 00:00:00       1500          0         30
      7876 ADAMS      CLERK           7788 1983.01.12 00:00:00       1100                    20
      7900 JAMES      CLERK           7698 1981.12.03 00:00:00        950                    30
      7902 FORD       ANALYST         7566 1981.12.03 00:00:00       3000                    20

flashback table process can automatically restores
all attributes associated with the table, such as indexes and triggers,
and maintains the dada integrity with preserving all dependent objects
and referential constraints.

However, there exists following limitations when performing the flashback table function:
- Executed within a single transaction
- Acquire exclusive DML locks
- Statistics are not flashbacked
- Can’t across DDL operation
- Can’t Flashback system tables

SCENARIO 5: FLASHBACK DROP TABLE
The current time is 12 PM on April 5, 2005. Your training DBA just told you that
he dropped the HR employee table. The table was dropped around 11:45 AM.
The database activity is minimal because most staff are currently in a meeting.
The table must be recovered.

# drop
SCOTT@TEST_T.WORLD>drop table emp ;
Table dropped.

# 원래 이름으로 원복
SCOTT@TEST_T.WORLD>flashback table emp to before drop ;
Flashback complete.

# drop
SCOTT@TEST_T.WORLD>drop table emp ;
Table dropped.

# 다른 이름으로 복구
SCOTT@TEST_T.WORLD>flashback table emp to before drop rename to employee ;
Flashback complete.

# drop
SCOTT@TEST_T.WORLD>drop table employee ;
Table dropped.

# 쓰레기통(user_recyclebin) 조회
SCOTT@TEST_T.WORLD>select object_name, original_name,type, ts_name, droptime
  2  from user_recyclebin where can_undrop ='YES';

OBJECT_NAME                    ORIGINAL_NAME   TYPE   TS_NAME  DROPTIME
------------------------------ --------------- ------ -------- -------------------
BIN$KecAh6AxUGTgQ8v2gjpQZA==$0 CHECK_F_BACK    TABLE  USERS    2007-02-20:19:35:34
BIN$KecAh6AyUGTgQ8v2gjpQZA==$0 CHECK_F_BACK    TABLE  USERS    2007-02-20:19:36:58
BIN$KfwhZLPcwK7gQ8v2gjrArg==$0 EMPLOYEE        TABLE  USERS    2007-02-21:20:48:46

# 쓰레기통(user_recyclebin) 조회
SCOTT@TEST_T.WORLD>show recyclebin
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
CHECK_F_BACK     BIN$KecAh6AyUGTgQ8v2gjpQZA==$0 TABLE        2007-02-20:19:36:58
CHECK_F_BACK     BIN$KecAh6AxUGTgQ8v2gjpQZA==$0 TABLE        2007-02-20:19:35:34
EMPLOYEE         BIN$KfwhZLPcwK7gQ8v2gjrArg==$0 TABLE        2007-02-21:20:48:46

As long as the space used by recycle bin objects is not reclaimed,
you can recover those objects by Flashback Drop. The space
used by the table and its dependent objects are not immediately reclaimable.
Generally, although the dropped table is in Recycle Bin, but its associated space
is reported in DBA_FREE_SPACE view because its space is automatically reclaimable.
Whenever the space is under pressure, it will be reclaimed automatically,
the recycle bin objects will be purged using FIFO mechanism, such as the table owner
creates a new table or adds data that causes the quota to be exceeded, or
DBA extends the file size within the tablespace to accommodate create/insert operations.
The space can be manually cleaned up with PURGE statement.

## Purge 하기

# Users tablespace 에 있는 쓰레기통 비우기
SCOTT@TEST_T.WORLD>purge tablespace users ;
Tablespace purged.

# Users tablespace 에 있는 쓰레기통 내용 중 owner 가 scott 인것만 비우기
SCOTT@TEST_T.WORLD>purge tablespace users user scott ;
Tablespace purged.

SCOTT@TEST_T.WORLD>purge user_recyclebin ;
Recyclebin purged.

SCOTT@TEST_T.WORLD>purge dba_recyclebin ;
DBA Recyclebin purged.

SCENARIO 6: FLASHBACK DATABASE 할차례

The current time is 12 PM on April 5, 2005. Your training DBA just told you that
he purged the HR employee table. The table was purged around 11:45 AM.
The database activity is minimal because most staff are currently
in a meeting. Definitely, you can not Flashback the droped
tables using Flashback Drop features. The table must be recovered.

It is fast, the time to restore a database is proportional to the
number of block changes that need to be backed out, not the size of the database.

To implement Flashback database feature, you need to configure flash recovery area
to provide a unified storage location for all recovery related files
(flashback database logs, archived redo logs, and RMAN backups) and
activities within the database.

Flashback database logs are the snapshot of changed blocks within the database
written by RVWR peridocally. Using the flashback database log plus redo logs
will make the recovery process faster and more efficient. The database recovery
will be in minutes instead of hours.

You may ask the performance overhead cost? Statistics show that the enabling
flashback database is less than 2%, which will be acceptable for trading off
the data loss and downtime.

Following is the implementation procesudres for Flashback Database:
Step 1: Make sure the database is in archive log mode.

SYS@TEST_T.WORLD>archive log list
Database log mode              Archive Mode
Automatic archival             Enabled
Archive destination            /a01b/TEST_T/arch/arch
Oldest online log sequence     59
Next log sequence to archive   62
Current log sequence           62


Step 2: Define Flash Recovery Area
b. Mannually configure Flash Recovery Area:
DB_RECOVERY_FILE_DEST : defining this parameter as a location and destination
                        for Flash Recovery files
DB_RECOVERY_FILE_DEST_SIZE : speifiy the disk limit, which is the amount of
                             space the flash area is permitted to use.

DB_RECOVERY_FILE_DEST_SIZE has to be specified before the DB_RECOVERY_FILE_DEST
initialization parameter. For using Oracle RAC, all instances must have the
same values for these two parameters.                            

more initTEST_T.ora

###########################################
# Flashback Database
###########################################
DB_RECOVERY_FILE_DEST=/u02b/ORACLE/FLASHBACK
DB_RECOVERY_FILE_DEST_SIZE=2G


SQL> show parameter recovery

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest                string      /u02b/ORACLE/FLASHBACK
db_recovery_file_dest_size           big integer 2G
recovery_parallelism                 integer     0

 

Step 3. Open the database in MOUNT EXCLUSIVE mode and turn on the flashback feature:

SQL> startup mount exclusive
ORACLE instance started.

Total System Global Area  293601280 bytes
Fixed Size                  1329584 bytes
Variable Size              94615120 bytes
Database Buffers          197132288 bytes
Redo Buffers                 524288 bytes
Database mounted.
SQL> alter database flashback on ;

Database altered.

Step 4: Set the Flashback Database retention target:


SQL> show parameter flash
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_flashback_retention_target        integer     1440

SQL> alter system set db_flashback_retention_target = 2000 ;
System altered.

SQL> show parameter flash
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_flashback_retention_target        integer     2000

However, this parameter[minutes] just defines a target number, not guaranteed.
The actual time period depends on the flashback log data in the flash recovery area.
To determine if Flashback Database is enabled, issue the following command:

SQL> select flashback_on from v$database ;

FLA
---
YES


Flashback Database commands can be executed with RMAN or SQL environments.
you need to open database with RESETLOGS after the flashback.

SYS@TEST_T.WORLD>create table check_flash_effect ( a1 number, a2 number ) ;
Table created.

SYS@TEST_T.WORLD>insert into check_flash_effect values ( 1,2 ) ;
1 row created.

SYS@TEST_T.WORLD>commit ;
Commit complete.

SYS@TEST_T.WORLD>select sysdate from dual ;

SYSDATE
-------------------
2007.02.22 18:56:38

SYS@TEST_T.WORLD>drop table check_flash_effect purge ;
Table dropped.
SYS@TEST_T.WORLD>show recyclebin

 


 select * from emp as of timestamp
                     to_timestamp('2007/02/21 185803','YYYY/MM/DD HH24MISS')
                     where ename ='MILLER' ;
SYS@s>flashback database to timestamp to_timestamp('2007.02.22 18:56:38','YYYY/MM/DD HH24:MI:SS');
flashback database to timestamp to_timestamp('2007.02.22 18:56:38','YYYY/MM/DD HH24:MI:SS')
*
ERROR at line 1:
ORA-38757: Database must be mounted EXCLUSIVE and not open to FLASHBACK.

SYS@s>startup mount exclusive
ORACLE instance started.

Total System Global Area  293601280 bytes
Fixed Size                  1329584 bytes
Variable Size              94615120 bytes
Database Buffers          197132288 bytes
Redo Buffers                 524288 bytes
Database mounted.
SYS@s>flashback database to timestamp to_timestamp('2007.02.22 18:56:38','YYYY/MM/DD HH24:MI:SS');

Flashback complete.

SYS@s>alter database open resetlogs ;

Database altered.

SYS@s>select * from check_flash_effect ;

        A1         A2
---------- ----------
         1          2

SCOTT@TEST_T.WORLD>create table check_flash_tablespace ( a1 number, a2 number ) tablespace users ;
Table created.

SCOTT@TEST_T.WORLD>insert into check_flash_tablespace values ( 1,2 ) ;
1 row created.

SCOTT@TEST_T.WORLD>commit ;
Commit complete.

SCOTT@TEST_T.WORLD>select sysdate from dual ;
SYSDATE
-------------------
2007.02.22 19:03:29

SCOTT@TEST_T.WORLD>drop table check_flash_tablespace ;
Table dropped.

Flashback Database feature has following limitations:
- Can’t use Flashback Database feature if the control file was restored
  or recreated after Flashback dabase is enabled
- A data file cannot be flashed back to a time before the RESIZE operation.
  This restriction only apply the manual RESIZE operation, not for automatic space extension
- Can’t flashback the media failures such as a data file or tablespace was
  dropped or corrupted. In this case, whenever a data file or tablespace is
  dropped, it is written to control file, and will be marked offline,
  it can not be flashed back. Need to recover the lost data file or tablespace
  after flashback operation.
- The SCN you want to flashback to must EXIST in the flashback logs.
  Due to space pressure, the flashback log may be deleted. In this case,
  you canot flashback your database to the SCN prior to the earlist SCN within
  the flashback logs.
 

#################

## Drop table 후 Table 복구 및 index/constraint Rename

## Sample Table 생성
SCOTT@TEST_T.WORLD>create table check_F ( a1 number, a2 number, a3 number ) ;
Table created.

## Sample Data Insert
SCOTT@TEST_T.WORLD>insert into check_f values ( 1,2,3 ) ;
1 row created.

SCOTT@TEST_T.WORLD>insert into check_f values ( 4,5,6 );
1 row created.

SCOTT@TEST_T.WORLD>insert into check_f values( 7,8,9 ) ;
1 row created.

15:33:46 SCOTT@TEST_T.WORLD>commit ;
Commit complete.

## Primary key Constraint 생성 및 PK Indesx 생성
15:33:50 SCOTT@TEST_T.WORLD> alter table check_f add constraint XPKcheck_F primary key ( a1 , a2 ) using index ;
Table altered.

## 추가 Index 생성
15:34:51 SCOTT@TEST_T.WORLD> create index index_check_f on check_F ( a3 );
Index created.

15:36:50 SCOTT@TEST_T.WORLD>select CONSTRAINT_NAME, CONSTRAINT_TYPE from user_constraints
15:36:58   2  where table_name ='CHECK_F';

CONSTRAINT_NAME                C
------------------------------ -
XPKCHECK_F                     P

15:37:59 SCOTT@TEST_T.WORLD>select index_name,index_type from user_indexes where table_name ='CHECK_F'


INDEX_NAME                     INDEX_TYPE
------------------------------ ---------------------------
XPKCHECK_F                     NORMAL
INDEX_CHECK_F                  NORMAL

## 우선 쓰레기통 청소

SCOTT@TEST_T.WORLD>conn / as sysdba
Connected.
Session altered.

SYS@TEST_T.WORLD>purge dba_recyclebin ;
DBA Recyclebin purged.

SYS@TEST_T.WORLD>select owner, original_name, operation, type, can_undrop from dba_recyclebin ;
no rows selected

## Constraint Drop 후  dba_recyclebin Check
SCOTT@TEST_T.WORLD>alter table check_f drop primary key ;
Table altered.

SCOTT@TEST_T.WORLD>select  owner, original_name, operation, type, can_undrop from dba_recyclebin ;
no rows selected

# 복구
SCOTT@TEST_T.WORLD>alter table check_f add constraint XPKcheck_F primary key ( a1 , a2 ) using index ;
Table altered.

## Index  Drop 후  dba_recyclebin Check
SCOTT@TEST_T.WORLD>drop index INDEX_CHECK_F;
Index dropped.

SCOTT@TEST_T.WORLD>select  owner, original_name, operation, type, can_undrop from dba_recyclebin ;
no rows selected

# 복구
SCOTT@TEST_T.WORLD>create index index_check_f on check_F ( a3 );
Index created.

SCOTT@TEST_T.WORLD>drop table check_f ;
Table dropped.
SCOTT@TEST_T.WORLD>select  owner,OBJECT_NAME, original_name, operation, type, can_undrop from dba_recyclebin ;

OWNER           OBJECT_NAME                    ORIGINAL_NAME        OPERATION TYPE                      CAN
--------------- ------------------------------ -------------------- --------- ------------------------- ---
SCOTT           BIN$KeTCcgks0AzgQ8v2gjrQDA==$0 CHECK_F              DROP      TABLE                     YES
SCOTT           BIN$KeTCcgkr0AzgQ8v2gjrQDA==$0 XPKCHECK_F           DROP      INDEX                     NO
SCOTT           BIN$KeTCcgkq0AzgQ8v2gjrQDA==$0 INDEX_CHECK_F        DROP      INDEX                     NO


## 복구 후 Constraint 및 Index Check
SCOTT@TEST_T.WORLD>flashback table CHECK_F to before drop ;
Flashback complete.

## 쓰레기 통이 깨끗해졌다.

SCOTT@TEST_T.WORLD>select  owner,OBJECT_NAME, original_name, operation, type, can_undrop from dba_recyclebin ;
no rows selected


SCOTT@TEST_T.WORLD>select index_name, status from user_indexes where table_name ='CHECK_F';

INDEX_NAME                     STATUS
------------------------------ --------
BIN$KeQzQI4A0AjgQ8v2gjrQCA==$0 VALID
BIN$KeQzQI3/0AjgQ8v2gjrQCA==$0 VALID

SCOTT@TEST_T.WORLD>select CONSTRAINT_NAME, CONSTRAINT_TYPE, status
                   from user_constraints where table_name ='CHECK_F';

CONSTRAINT_NAME                C STATUS
------------------------------ - --------
BIN$KeQzQI3+0AjgQ8v2gjrQCA==$0 P ENABLED

## Valid  상태인 Index 사용 가능한지 체크

SCOTT@TEST_T.WORLD>set autotrace traceonly
SCOTT@TEST_T.WORLD>select * from check_f ;
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=3 Card=3 Bytes=117)
   1    0   TABLE ACCESS (FULL) OF 'CHECK_F' (TABLE) (Cost=3 Card=3 Bytes=117)

## 강제 Hint 를 통해서 Index 타게

SCOTT@TEST_T.WORLD>select /*+ INDEX(check_f) */ * from check_f
  2  ;


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=2 Card=3 Bytes=117)
   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'CHECK_F' (TABLE) (Cost=2 Card=3 Bytes=117)
   2    1     INDEX (FULL SCAN) OF 'BIN$KeQzQI4A0AjgQ8v2gjrQCA==$0' (INDEX (UNIQUE)) (Cost =1 Card=3)

SCOTT@TEST_T.WORLD>set autotrace off

## Index Rename

SCOTT@TEST_T.WORLD>select index_name, status from user_indexes where table_name ='CHECK_F';

INDEX_NAME                     STATUS
------------------------------ --------
BIN$KeTCcgkr0AzgQ8v2gjrQDA==$0 VALID
BIN$KeTCcgkq0AzgQ8v2gjrQDA==$0 VALID

SCOTT@TEST_T.WORLD>alter index "BIN$KeTCcgkr0AzgQ8v2gjrQDA==$0" rename to XPKCHECK_F ;
Index altered.

SCOTT@TEST_T.WORLD>alter index "BIN$KeTCcgkq0AzgQ8v2gjrQDA==$0" rename to INDEX_CHECK_F ;
Index altered.

SCOTT@TEST_T.WORLD>select index_name, status from user_indexes where table_name ='CHECK_F';

INDEX_NAME                     STATUS
------------------------------ --------
XPKCHECK_F                     VALID
INDEX_CHECK_F                  VALID

# Constraint
SCOTT@TEST_T.WORLD>select CONSTRAINT_NAME, CONSTRAINT_TYPE, status from user_constraints where table_name ='CHECK_F';

CONSTRAINT_NAME                C STATUS
------------------------------ - --------
BIN$KeTCcgkp0AzgQ8v2gjrQDA==$0 P ENABLED


  1  select CONSTRAINT_NAME, CONSTRAINT_TYPE, status
  2* from user_constraints where table_name ='CHECK_F'
SCOTT@TEST_T.WORLD>/

CONSTRAINT_NAME                C STATUS
------------------------------ - --------
BIN$KeTCcgkp0AzgQ8v2gjrQDA==$0 P ENABLED

SCOTT@TEST_T.WORLD>insert into check_F values ( 1,2,3 ) ;
insert into check_F values ( 1,2,3 )
*
ERROR at line 1:
ORA-00001: unique constraint (SCOTT.BIN$KeTCcgkp0AzgQ8v2gjrQDA==$0) violated

SCOTT@TEST_T.WORLD>select CONSTRAINT_NAME, CONSTRAINT_TYPE, status from user_constraints where table_name ='CHECK_F' ;

CONSTRAINT_NAME                C STATUS
------------------------------ - --------
BIN$KeTCcgkp0AzgQ8v2gjrQDA==$0 P ENABLED

SCOTT@TEST_T.WORLD>alter table check_f rename constraint "BIN$KeTCcgkp0AzgQ8v2gjrQDA==$0" to XPKCHECK_F ;
Table altered.

SCOTT@TEST_T.WORLD>select CONSTRAINT_NAME, CONSTRAINT_TYPE, status from user_constraints where table_name ='CHECK_F' ;
CONSTRAINT_NAME                C STATUS
------------------------------ - --------
XPKCHECK_F                     P ENABLED 


반응형
Posted by [PineTree]
ORACLE/TroubleShooting2010. 8. 12. 10:18
반응형

ORA-01031

증상 : sys, system 계정으로 원격접속이 안됨.
DB를 다른 서버로옮기고 확인을 위해 원격접속을 하려고 하면 sys 계정에서
ORA-01031: insufficient privileges
에러가 발생합니다.
sqlplus /nolog
sql> conn
sys/oracle@orcl as sysdba
이런식으로 접근하는데 as sysdba 붙여서 그런지 접속이 되지 않더군요
로컬에서는 잘 되고 다른 일반계정들은 원격접속도 잘 됩니다.
as sysdba를 붙여 로그인 하는 방법은 Oracle의 Password인증방식을 이용한다. 

이때 두가지 경우를 확인하여야 하는데
첫째 : 패스워드 인증방식으로 로그인 할 수 있는 유저확인
둘째 : 패스워드 파일이 잘못되었을 경우

첫번째로 패스워드 인증방식을 쓸수있는 유저가 누구인지 먼저 알아보자.
SQL> select * from v$pwfile_users;
USERNAME                           SYSDB SYSOP
------------------------------ ----- -----
SYS                                     TRUE  TRUE
TEST_USER                           TRUE  FALSE


SYSTEM 계정을 원격으로 접속하기 위해 추가 해본다.
SQL> show user;
USER은 "SYS"입니다

SQL> grant sysdba to system;
권한이 부여되었습니다.

SQL> select * from v$pwfile_users;
USERNAME                           SYSDB SYSOP
------------------------------ ----- -----
SYS                                     TRUE  TRUE
TEST_USER                           TRUE  FALSE
SYSTEM                               TRUE  FALSE

위와 같이 권한을 부여하면 간단하게 SYSTEM 계정으로 원격접속 할 수 있다. 

두번째의 경우는 orapw파일을 이용하여 패스워드를 재설정 하는 방법을 알아보자.
아래의 방법은 정리가 잘되어있는 문서를 인용하겠습니다.
출처는 Oracle Forum Technical Bulletin 의 문서를 인용하였습니다.

AS SYSDBA로 접속할때 PASSWORD 걸기
============================

PURPOSE
-------
AS SYSDBA로 접속할 때 PASSWORD 설정하는 방법

Explanation
-----------
오라클 9i에서는 internal로 접속을 하였을 때 ORA-09275: CONNECT INTERNAL is not a valid DBA connection 를 경험할 수 있다.
오라클 9i 서버에서는 connect internal을 사용하지도 않고, as sysdba와 as sysoper로 logon하여 DATABASE를 구동할 수 있다.

여기서 다루고자 하는 것은 Platform에 관계없이 oracle dba group이라면 기존에는 password를 점검하지 않고 사용할 수 있었다.
그러나, 여러가지 보안상의 이유로 password를 걸었을 때 ORA-01031: insufficient privileges와 같은 message나, password를 묻지않고 bypass하는 경우를 알아보고자 한다.

<Note> 9i에서는 svrmgrl command가 없어 졌으며 sqlplus internal도 사용할 수 없다.

Explanation
-----------
1. OS 및 Platform에 관계없이 $ORACLE_HOME/dbs 디렉토리에서 오라클사용자로 orapwd tool을 사용하여 password file을 생성한다.
기존에 password file이 존재한다면 password 파일을 Remove 또는 rename하여 별도로 보관하여도 된다.

Usage: orapwd file=<fname> password=<password> entries=<users>

where
file - name of password file (mand),
password - password for SYS and INTERNAL (mand),
entries - maximum number of distinct DBA and OPERs (opt),
There are no spaces around the equal-to (=) character.

$orapwd file=orapw<SID> password=[password]
$orapwd file=orapw<SID> password=[password] entries=10
<Note> 위와 같이 하였을때 생성된 password 파일의 크기는 차이기 있을수 있다.
2. init.ora를 사용하는 경우init<SID>.ora file를 편집기로 open한 다음 아래처럼 기술한다.
대소문자의 구분은 없습니다.
REMOTE_LOGIN_PASSWORDFILE = EXCLUSIVE
3. spfile을 사용하는 경우 아래의 절차처럼 dynamic하게 변경하여 주어야 한다.
SQL> show parameter spfile
NAME TYPE VALUE
---------- ---------- ---------
spfile string
?/dbs/spfile@.ora

SQL
> show parameter remote
NAME TYPE VALUE
------------------------------------ ----------- ---------------
remote_archive_enable boolean TRUE
remote_dependencies_mode string TIMESTAMP
remote_listener string
remote_login_passwordfile string
remote_os_authent boolean FALSE
remote_os_roles boolean FALSE

SQL> alter system set remote_login_passwordfile=exclusive scope=spfile ;
System altered.

SQL> show parameter spfile
NAME TYPE VALUE
------------------------------------ ----------- ------------------
spfile string
?/dbs/spfile@.ora

SQL
> show parameter remote
NAME TYPE VALUE
------------------------------------ ----------- ---------------
remote_archive_enable boolean TRUE
remote_dependencies_mode string TIMESTAMP
remote_listener string
remote_login_passwordfile string EXCLUSIVE
remote_os_authent boolean FALSE
remote_os_roles boolean FALSE

4. SQLNET.ORA 파일 편집.
password를 설정하기 위해서는 반드시 아래와 같이 sqlnet.ora 파일을 에디터로 open한 다음 아래처럼 기술하여야 한다.

$ echo $TNS_ADMIN
/d02/rctest/app/oracle/product/9.0.1/networ/admin

SQLNET.AUTHENTICATION_SERVICES = (NONE)

5. 위와 같은 작업을 순서대로 하였고 password를 정상적으로 입력하였는데도 logon이 되지 않는다면 1031, 00000, "insufficient privileges" 같은 message가 계속 나타난다면 orapwd를 password와 sys user의 password가 일치하는지를 확인한 다음 sqlplus로 접속하여야지만 아래처럼 정상적으로 logon를 할 수 있다.

Example
-------
[ora9i:/d02/rctest]sqlplus "/as sysdba"
SQL*Plus: Release 9.0.0.0.0 - Beta on Thu May 30 10:55:46 2002 (c) Copyright 2001 Oracle Corporation. All rights reserved.

ERROR:
ORA-01031: insufficient privileges

Enter user-name: sys
Enter password: ----> password와 as sysdba 를 함께 입력

Connected to:
Oracle9i Enterprise Edition Release 9.0.0.0.0 - Beta
With the Partitioning option
JServer Release 9.0.0.0.0 - Beta

SQL>
[ora9i:/d02/rctest]sqlplus /nolog
SQL*Plus: Release 9.0.0.0.0 - Beta on Thu May 30 10:57:45 2002 (c) Copyright 2001 Oracle Corporation. All rights reserved.

SQL> connect sys/manager
ERROR: ORA-28009: connection to sys should be as sysdba or sysoper

SQL> connect sys/manager as sysdba
Connected.
SQL>

출처 : http://www.function.kr/tc/59
반응형
Posted by [PineTree]
DBMS2010. 8. 9. 13:37
반응형

출처 : http://soff.tistory.com/106


이번 회에는 DB2 애플리케이션 개발 중에 오라클 DB 상이한 구문과 SQL 차이점에 대해서 설명하도록 하겠다. 출시될 DB2 Viper 2에서는 오라클 DB에서만 사용하는 outer join + 구문이나 connect by Recursive SQL, row number, 오라클 DB 전용 함수들이 DB2 레지스터리 변경 이후에 오라클 DB 동일하게 사용할 있어져서 오라클 DB 사용자들의 DB2 사용이 용이해 졌다.

 

Data Type

오라클 DB DB2 데이터 타입의 차이점은 DB2에서의 데이터 타입은 사용자 편의보다는 옵티마이저가 가장 해석할 있도록 세분화 되어 있다는 점이다. 이는 DB2 기본적으로 오라클 DB 달리 Rule base 옵티마이저 모드를 지원하지 않기에 옵티마이저가 최대한 해석할 있도록 만들어 주기 위함으로 보인다.

예를 들어 오라클 DB에서의 number 같이 정수, 소수를 대표하는 Data Type DB2에서는 크기에 따라 SMALLINT, INTEGER, BIGINT, DECIMAL(p,s)등으로 세분화 되어 쓰여지게 되어 있다.

 

Oracle Data Type

DB2 Data Type

Scope (DB2)

CHAR(n)

CHAR(n)

254 byte

VARCHAR2(n)

VARCHAR(n)

32,672 byte

LONG

LONG VARCHAR(n)

32,700 byte

NUMBER

SMLLINT

+ - 32,768 (5 digits, 2byte)

INTEGER

2 147 483 648 (10 digits, 4byte)

BIGINT

9,223,372,036,854,775,808 (64bit integers, 8type)

DECIMAL(p,s)

NUMERIC(p.s)

정밀도 31

REAL

 

DOUBLE (FLOAT)

+2.225E-307

BLOB

BLOB(n)

2GB

CLOB

CLOB(n)

2GB

NCLOB

DBCLOB

2GB

DATE

TIMESTAMP

0001-01-01-00.00.00.000000

DATE

0001-01-01

~ 9999-12-31

TIME

00:00:00

~ 24:00:00

DB2 오라클 DB에서와 같이 숫자와 문자간 자동 변환을 지원하지 않는다 따라서 문자와 숫자간 비교나 조인시 반드시 CAST, INT, CHAR 함수 등으로 변환을 해주어야 한다.

>

select * from tab1 where col1 = int(‘1’)

select * from tab1 where col1 = cast (‘1’ as int)

 

DB2에서의 날짜 연산

1.       to_char() 함수: DB2에도 오라클 DB to_char() 동일한 이름의 함수는 있으나 오라클 DB에서와 같이 날짜 형식의 다양한 포멧팅을 지원하지는 않는다. 오라클 DB TO_CAHR() 함수를 쓰기 위해서는 별도의 UDF 필요하다.(오라클/MS-SQL Built in Function 대한 DB2 UDF 첨부되어 있는 zip 파일을 참조해서 사용하기 바란다.)

2.       sysdate(oracle) => current date(현재 날짜), current timestamp (현재 시간소인)

3.       hex(current date) à 문자열 YYYYMMDD 형식 > 20080101

4.       date / year / month / day 함수 à 입력된 시간소인(혹은 날짜형식 문자열) 날짜(date yyyy-mm-dd), 년도(year –yyyy), (month – mm 2월인 경우 02 아니고 2 표시됨), (day – dd) 변환하는 scalar 함수

5.       날짜 더하기/ 빼기 “+/- n days”, “+/- months”, “+/- years” >current date + 1 months

6.       날짜끼리 경우 결과는 YYYYMMDD(decimal(8,0))형식으로 일자 사이의 기간을 나타내게 . ) values(date('2008-02-10') -date('2007-01-01')); à 00010109 (1 1개월 9)

7.       날짜 포멧 변경

char(current date, iso) – 2008-01-01

char(current date, eur) – 01.01.2008

char(current date, usa) – 01/01/2008

 

Page navigation 위한 Row Number

OLAP 함수인 row_number() over(order by 컬럼이름) 대체해서 사용해야 한다.

Select empno, fullname
From
(select empno
                  
, firstnme || ' ' || lastname as fullname
                  
, row_number() over (order by empno) as r_num
                             from
employee ) as t1
Where
r_num >= 10 and r_num <20

 

Dummy Table

Sysibm.sysdummy1 (DB2)

select * from sysibm.sysdummy1

Truncate Table

DB2에서는 오라클 DB에서의 Truncate table 존재하지 않는다. DB2에서 테이블의 데이터를 효율적으로 지우는 방법은 아래와 같다.

Import from /dev/null of del replace into 테이블이름

Alter table 테이블이름 activate not logged initially with empty table

à ALTER TABLE EMPLOYEE ACTIVATE NOT LOGGED INITIALLY WITH EMPTY TABLE;

 

Decode

Decode문은 지원하지 않는다. Case문으로 대체해야 한다.

 

UPDATE staff

SET comm = salary + DECODE(job,'Mgr',100,0)

 

UPDATE staff

SET comm = salary + CASE job

WHEN 'Mgr' THEN 100 ELSE 0 END

 

NULL 처리

Oracle

DB2

NVL(TO_CHAR(MGR_ID),'No Manager')

 

COALESCE(MGR _ID,'No Manager')

VALUE(MGR _ID,'No Manager')

 

Outer join

(+) 기호를 지원하지 않음으로, RIGHT OUTER JOIN / LEFT OUTER JOIN / FULL OUTER JOIN으로 대체해야 한다.


 

Sequence

데이터베이스 전체에서 관리되는 Sequence 별도로 테이블마다 제공되는 컬럼 sequence 존재한다. 사용법은 아래와 같다.

 

Oralce

DB2

시스템

시퀀스 정의

Create sequence test_seq start with 1

Increment by 1

Create sequence test_seq start with 1

Increment by 1

시퀀스 사용

Test_seq.nextval

Test_seq.currval

Nextval for test_seq

Prevval for test_seq

 

Procedure

1.       프로시저 생성시 CREATE OR REPLACE 옵션을 제공하지 않는다. 따라서 이미 존재하고 있는 프로시저일 경우 Drop 재생성 해야 한다. 이때 프로시저를 참조하는 Routine 있으면 같이 Drop하고 생성해 주어야 한다.

2.       데이터 타입 정의시 반드시 길이를 정해 주어야 한다. 길이가 정해져 있지 않은 데이터 타입은 사용이 불가능 하다. 또한 참조되는 객체의 길이가 서로 다를 경우 생성되지 않으므로 참조되는 객체의 길이와 타입은 반드시 동일하게 생성해 주어야 한다.

3.       /출력 값에 설정시 IN, OUT, INOUT 변수 앞에 선언하고 변수와 변수 타입(크기가 명시된) 선언한다.

4.       LANGUAGE SQL 옵션은 ver7.x에서는 반드시 써야 하지만 ver8.x부터는 선택 사항이다.

5.       Procedure 호출은 Call 명령어를 통해 호출한다.

à Call stored_procedure_name (input1, input2….)

 

CREATE OR REPLACE PROCEDURE test_sum_pr (i_log IN DATE, i_type IN VARCHAR2)

à CREATE PROCEDURE test_sum_pr (IN  i_log  DATE, IN i_type  VARCHAR(10))

 

Temporary Table

Temporary table 사용하기 위해서는 반드시 사용자 임시 테이블 스페이스 타입의 테이블 스페이스가 존재해야 하며, 세션에 독립적으로 생성되어 세션이 종료됨과 함께 자동으로 소멸된다.

 

-- User Temp 테이블 스페이스 작성

CREATE USER TEMPORARY TABLESPACE apptemps

MANAGED BY SYSTEM USING ('apptemps');

 

-- Temp Table 작성

DECLARE GLOBAL TEMPORARY TABLE t_employees LIKE employee NOT LOGGED;

 

Trigger

1.       트리거 생성시 CREATE OR REPLACE 옵션을 제공하지 않는다. 따라서 이미 존재하는 트리거일 경우 drop 생성해야 한다.

2.       Before 트리거에서 NO CASCADE 옵션은 필수 항목이다.

3.       MODE DB2SQL 옵션은 필수 항목이다.

4.       UPDATE & DELETE 구문은 Before&After 사용해야 한다.

5.       오라클 DB INSERT OR UPDATE OR DELETE ON 같은 다중 역할을 하는 트리거 생성이 불가능하다. 따라서 역할에 따라 트리거를 별도로 생성해 주어야 한다.

6.       INNER SQL(Select .. INTO) 통한 변수 설정이 불가능 하기 때문에 반드시 SET 통해 SELECT 결과를 변수에 입력하여야 한다. 이때 SELECT 문장의 값은 반드시 단일 Row여야 한다.

 

ID_EVENT (crud char(1), id varchar(40), name varchar(40))

ID_LOG (seq int, crud char(1), id varchar(40), name varchar(40), date date)

Oracle

CREATE OR REPLACE TRIGGER ID_EVENT_TR

AFTER INSERT OR UPDATE OR DELETE ON ID_EVENT

FOR EACH ROW

DECLARE

  ret binary_integer;

  crud char(1);

  vid varchar2(40);

  vname varchar2(40);

BEGIN

  if inserting then

    crud := 'C';    vid := :new.ID;    vname := :new.NAME;

  elsif deleting then

    crud := 'D';    vid := :old.ID;    vname := :old.NAME;

  else

    crud := 'U';     vid := :old.ID;     vname := :old.NAME;

  end if;

insert into ID_LOG (seq, crud, id, name, date)

values (test.nextval, crud, vid, vname ,sysdate);

END;

DB2

CREATE TRIGGER ID_EVENT_TR_DEL1
  AFTER  DELETE  ON
ID_EVENT
 
REFERENCING  OLD AS OLD
  FOR EACH ROW
  MODE DB2SQL
  BEGIN ATOMIC
    DECLARE
ret DECIMAL(31,0);

    DECLARE
crud CHAR(1);
    DECLARE
vid VARCHAR(40);
    DECLARE
vname VARCHAR(40);
    SET
crud = 'D';
    SET
vid = OLD.ID;
    SET
vname = OLD.DOC_ID;
   insert into
ID_LOG (seq, crud, id, name, date)
      VALUES
(nextval FOR test, crud, vid, vname ,current date);
  END
;

CREATE TRIGGER
ID_EVENT_TR_INS1
  AFTER   INSERT  ON
ID_EVENT
 
REFERENCING   NEW AS NEW
  FOR EACH ROW
  MODE DB2SQL
  BEGIN ATOMIC
    DECLARE
ret DECIMAL(31,0);

    DECLARE
crud CHAR(1);
    DECLARE
vid VARCHAR(40);
    DECLARE
vname VARCHAR(40);
    SET
crud = 'C';
    SET
vid = NEW.ID ;
    SET
vname = NEW.NAME;
   insert into
ID_LOG (seq, crud, id, name, date)
      VALUES
(nextval FOR test, crud, vid, vname ,current date);
  END
;

CREATE TRIGGER
ID_EVENT_TR_UPD1
  AFTER  UPDATE  ON
ID_EVENT
 
REFERENCING    OLD AS OLD     NEW AS NEW
  FOR EACH ROW
  MODE DB2SQL
  BEGIN ATOMIC
    DECLARE
ret DECIMAL(31,0);

    DECLARE
crud CHAR(1);
    DECLARE
vid VARCHAR(40);
    DECLARE
vname VARCHAR(40);
    SET
crud = 'U';
    SET
vid = OLD.ID ;
    SET
vname = OLD.NAME;
   insert into
ID_LOG (seq, crud, id, name, date)
      VALUES
(nextval FOR test, crud, vid, vname ,current date);
  END
;

 

Function

Built-in 함수를 제외하고 유저에 의해 생성된 Function UDF(User Define Function) 한다.

1.       Input parameter 선택 사항이지만 가로는 필수 사항이다.

2.       Return Type 아래 3가지 하나는 반드시 명시되어야 한다.

A.      Scalar: 단일 반환

B.      Table: From절에 사용되는 Table 반환

C.      Row: Transform 함수로 사용되면 하나의 row 반환

3.       LANGUAGE SQL V8부터 옵션 사항이다.

4.       Return 키워드 후에는 반드시 SQL 함수 Body 작성해야 한다.

 

예제)

DB2 LAST_DAY 함수

CREATE FUNCTION DB2DEV.LAST_DAY (D DATE)

  RETURNS DATE

  SPECIFIC DB2APP.LAST_DAYDATE

  LANGUAGE SQL

RETURN D + 1 month - day(D + 1 month) day;

 

오라클 DB LAST_DAY 함수

CREATE FUNCTION months_between(d1 TIMESTAMP, d2 TIMESTAMP)

    RETURNS FLOAT

    LANGUAGE SQL

RETURN 12*(year(d1) - year(d2)) + month(d1) - month(d2)

+ (TIMESTAMPDIFF(2,CHAR(d1 - (d2 + (12*(year(d1) - year(d2))        

+ month(d1) - month(d2)) MONTHS))) / 2678400.0)

 

SQL PL (Oracle PL/SQL)

변수 정의와 규칙

Oracle PL/SQL 같은 경우 아래의 4가지 위치에 변수 정의가 가능하다.

1.       스토어드 프로시저 또는 함수 파라미터 리스트

2.       스토어드 프로시저, 함수, 트리거의 내부

3.       패키지 정의

4.       패키지 body 정의

 

DB2에서는 오라클 DB에서와 같이 함수나 프로시저를 그룹화하는 패키지 개념이 없다. 따라서 변수 정의는 패키지를 제외한 위의 가지 경우만 허용된다.

DB2 SQL PL에서도 native data type user defined distinct type 여러 형태 정의가 가능하다. 변수 정의시 반드시 DECLARE 구문을 써서 정의하여야 하며, 변수 정의를 위해서는 반드시 BEGIN … END 블록 안에서 정의되어야 한다. 초기값 설정 이후 변수에 값을 설정할 경우 DB2에서는 SET 문장을 써서 변수를 assign 한다.

 

> 초기값 설정

Oracle PL/SQL: l_value NUMBER(10,2) :=0.0;

DB2 SQL PL:  DECLARE l_value NUMERIC(10,2) DEFAULT 0.0;

 

> 변수 할당

Oracle PL/SQL: l_value = 99.99;

DB2 SQL PL: SET l_value = 99.99;

à Trigger 경우 INNER SQL(Select .. INTO) 통한 변수 설정이 불가능 하기 때문에 반드시 SET 통해 SELECT 결과를 변수에 입력하여야 한다. 이때 SELECT 문장의 값은 반드시 단일 Row여야 한다.

SET l_value =(SELECT balance from account_info where account_no = actNo);

 

Cursor 처리

1.       응용프로그램에서 결과 집합을 검색하기 위해 사용하는 기법으로 Select 문에서 여러 건의 데이터를 반환하는 경우에 사용된다.

2.       커서는 declare / open / fetch / close 단계로 사용된다.

3.       Open 커서는 UOW(unit of work) 종료시(commit / rollback) 소멸되지만 DB2에서는 With HOLD 옵션으로 커서의 위치를 유지할 있다.

4.       DB2 Memory level Lock 사용하며 그에 따른 Cursor 유형도 읽기 전용(READ ONLY) 업데이트 가능한 UPDATEABLE 커서가 있다.

5.       UPDATEABLE(FOR UPDATE OF) 사용하면 데이터를 Fetch 하는 동안 S모드 대신 U모드 LOCK 적용되어 Deadlock 방지할 있다.

 

Oracle

DB2

용도

CURSOR cursor_name

[(cursor_parameter(s))]

IS select_statement;

DECLARE cursor_name

CURSOR [WITH HOLD] [WITH RETURN] [TO CALLER | TO CLIENT] FOR select-statement

[FOR READ ONLY|UPDATE OF|]

Declare

OPEN cursor_name

[(cursor_parameter(s))];

OPEN cursor_name [USING

host-variable]

Open

FETCH cursor_name INTO

variable(s)

FETCH [from] cursor_name

INTO variable(s)

Fetch

UPDATE table_name

SET statement(s)...

WHERE CURRENT OF

cursor_name;

UPDATE table_name

SET statement(s)...

WHERE CURRENT OF

cursor_name

Update Fetch

DELETE FROM table_name

WHERE CURRENT OF

cursor_name;

DELETE FROM table_name

WHERE CURRENT OF

cursor_name

Delete Fetch

CLOSE cursor_name;

CLOSE cursor_name

Close

 

커서 예외 처리

Oracle

DB2

%ISOPEN

Open cursor에서 커서가 이미 열려 있는 상태면 SQLCODE = -501 / SQLSTATE=24501

Fetch에서 커서가 아직 열려 있지 않은 상태면 SQLCODE = -502 / SQLSTATE=24502

Oracle

IF c1%ISOPEN THEN

        fetch c1 into var1;

ELSE    -- cursor is closed, so open it

      OPEN c1;

      fetch c1 into var1;

END IF;

DB2

DECLARE cursor_notopen CONDITION FOR SQLSTATE 24501;

DECLARE CONTINUE HANDLER FOR cursor_notopen

   BEGIN

         open c1;

         FETCH c1 int var1;

   END;

     ...

   FETCH c1 into var1;

%NOTFOUND

SQLCODE = 100이거나 SQLSTATE = ‘02000’

Oracle

OPEN cur1;

LOOP

   FETCH cur1 INTO v_var1;

   EXIT WHEN cur1%NOTFOUND;

      ...

   END LOOP;

DB2

DECLARE SQLCODE int DEFAULT 0;

   ……

   OPEN c1;

   L1: LOOP

         FETCH c1 INTO v_var1;

         IF SQLCODE = 100 THEN

                 LEAVE L1;

         END IF;

         ...

   END LOOP L1;

%FOUND

SQLCODE = 0이거나 SQLSTATE = ‘00000’

Oracle

DELETE FROM emp  WHERE empno = my_empno;

   IF SQL%FOUND THEN    -- 행이 삭제 되었을 경우

      INSERT INTO emp_table

VALUES (my_empno, my_ename);

DB2

DELETE FROM emp WHERE empno = my_empno;

IF SQLCODE = 0  THEN    -- delete succeeded

   INSERT INTO emp_table VALUES (my_empno, my_ename);

%ROWCOUNT

Fetch First n rows only 사용하거나 Loop 사용하여 count 증가

exit/GET DIAGNOSTICS 문을 사용하여 반환된 계산

Oracle

LOOP

     FETCH c1 INTO my_ename,my_deptno;

     IF c1%ROWCOUNT > 10 THEN

        EXIT;

    END IF;

      ...

END LOOP;

 

DELETE FROM emp_table

WHERE ...

IF SQL%ROWCOUNT > 10 THEN     

-- 10 이상 삭제

      ...

   END IF;

DB2

DECLARE rc INT DEFAULT 0;

   …….

   DELETE FROM emp_table WHERE ...

   GET DIAGNOSTICS rc = ROW_COUNT;

   IF rc > 10 THEN      ...

   END IF;

GET DIAGNOSTICS SELECT /SELECT INTO 문장은 지원하지 않는다.

개의 ROW SELECTING 되지 않을 경우 SQLCODE = 100

하나의 ROW SELECTING 경우 SQLCODE=0

하나의 ROW 이상이 SELECTING 경우 SQLCODE=-811 (SQLSTATE=21000 – SQLERROR)

       

 

Debugging

DB2에는 오라클 DB dbms.output.put_line 같은 함수가 존재 하지 않는다. 따라서 dbms.output.put_line 함수와 같은 UDF Fuction 만들거나, 디버깅 테이블을 만들어 디버깅 하고자 하는 값을 새로 만든 디버깅 테이블에 Insert 하는 방법이 있다.

아래의 방법은 put_line UDF 생성하여 디버깅 하는 방법에 대한 설명이다. 해당 원문은 아래의 Site에서 확인 하기 바란다.

http://www.ibm.com/developerworks/db2/library/techarticle/0302izuha/0302izuha.html

 

put_line UDF생성 방법

CREATE PROCEDURE TESTCASE() RESULT SETS 0 LANGUAGE SQL

L_TESTCASE:

BEGIN NOT ATOMIC 

                  DECLARE V_DEPTNO               SMALLINT;

                  DECLARE V_DEPTNAME           VARCHAR(20);

                  DECLARE V_DIVISION               VARCHAR(20);

-- FOR DEBUG

                  DECLARE V_NUM     SMALLINT DEFAULT 0;

                  DECLARE V_MSG1   VARCHAR(4000);

                  DECLARE V_MSG2   VARCHAR(1);

-- END

-- SAMPLE1

                  SET V_NUM=2000;

                  SET V_MSG1='debugging start';

                  VALUES(PUT_LINE(V_NUM,V_MSG1)) INTO V_MSG2;

-- SAMPLE2

                  VALUES(PUT_LINE(SMALLINT(2),'this is no2')) 

                    INTO V_MSG2;

-- SAMPLE3

                  VALUES(PUT_LINE(3)) INTO V_MSG2;

-- SAMPLE4

                  VALUES(PUT_LINE('##number4##')) INTO V_MSG2;

-- SAMPLE5

                  SET V_NUM = 0;

   FOR V_C1_REC AS C1 CURSOR FOR

                  SELECT DEPTNUMB, DEPTNAME, DIVISION

                  FROM ORG ORDER BY DEPTNUMB DESC

   DO

              SET V_DEPTNO   = v_C1_REC.DEPTNUMB;

                  SET V_DEPTNAME = v_C1_REC.DEPTNAME;

                 SET V_DIVISION = v_C1_REC.DIVISION;

                  SET V_NUM = V_NUM + 1;

                  SET V_MSG1 ='DEPTNO=' || CHAR(V_DEPTNO)||',' ||'DEPTNAME='||V_DEPTNAME||','

                                   ||'DIVISION='||V_DIVISION;

                  VALUES(PUT_LINE(V_NUM,V_MSG1)) INTO V_MSG2;

   END FOR;

                  VALUES(PUT_LINE(32000,'end of the program')) 

                    INTO V_MSG2;

END          L_TESTCASE

 

<참조>

§   Oracle to DB2 UDB Conversion Guide(IBM.com/redbooks)

§   DB2 사용자 가이드(IBM)


반응형
Posted by [PineTree]