BLOG main image
전체보기 (77)
PHP (0)
JAVA (2)
ORACLE (5)
DB2 (0)
NETWORK (0)
LINUX (14)
etc... (6)
일상 (50)
Visitors up to today!
Today hit, Yesterday hit
daisy rss
tistory 티스토리 가입하기!
'ORACLE'에 해당되는 글 5건
2011. 11. 13. 21:25

Oracle에서 EXISTS사용 시 조건에 맞는 ROW만 출력 해준다.

IN은 실제로 존재하는 데이터를 모두 확인하지만

EXISTS 해당 ROW가 존재하는지만 체크하고 실행되지 않는다.

따라서 IN에 비하여 쿼리성능이 좋다.



SELECT     
    A.OPER_CD AS OPER_CD
    ,A.REST_CD AS REST_CD
    ,TO_CHAR(TO_DATE('20111113','YYYYMMDD')+1,'YYYYMMDD') AS DEAL_DAY
    ,A.SC_DEAL_CD    AS SC_DEAL_CD  
    ,A.SC_GB         AS SC_GB      
  FROM REST_MST  A 
  ,  SCDELL_MST  B 
  WHERE A.REST_CD  = 'G_10'
  AND  A.OPER_CD  = 'AS0000'
  AND  A.REST_CD  = B.REST_CD
  AND  A.SC_DEAL_CD = B.SC_DEAL_CD
  AND  A.SC_GB   = B.SC_GB
  AND   A.DEAL_DAY = '20111113'
  AND   B.USE_GB  = '1'
  AND NOT EXISTS (SELECT 1
               FROM REST_MST  B
            WHERE B.OPER_CD = A.OPER_CD
            AND B.REST_CD = A.REST_CD
            AND B.SC_GB = A.SC_GB
            and B.SC_DEAL_CD = A.SC_DEAL_CD
            AND B.DEAL_DAY = TO_CHAR(TO_DATE('20111113','YYYYMMDD')+1,'YYYYMMDD')
2011. 6. 15. 17:03

원인분석


Profile을 확인해보자.

SQL> select profile from dba_users where username = 'aaaa';

PROFILE
---------
DEFAULT


그럼 'PASSWORD_GRACE_TIME', 'PASSWORD_LIFE_TIME'이 DEFAULT Profile에서 어떻게 설정되어있는지 보자.

SQL> select limit, resource_name from dba_profiles where resource_name 
        in ('PASSWORD_GRACE_TIME', 'PASSWORD_LIFE_TIME', 'PASSWORD_REUSE_MAX', 
        PASSWORD_REUSE_TIME') and PROFILE = (select profile from dba_users where
        username = 'aaaa');

LIMIT            RESOURCE_NAME
-----------  ------------------------
180               PASSWORD_LIFE_TIME
UNLIMITED    PASSWORD_REUSE_TIME
UNLIMITED    PASSWORD_REUSE_MAX
7                  PASSWORD_GRACE_TIME

PASSWORD_REUSE_TIME과 PASSWORD_REUSE_MAX는 서로 관련이 있다.
PASSWORD_REUSE_TIME는 패스워드가 재사용되지 못하는 기간을 정의한다.
PASSWORD_REUSE_MAX는 현재 패스워드가 재사용되기 전에 몇 번이나 패스워드를 바꿀 것을 요청하는지를 정의한다.

이번 문제를 처리하기 위해서는 PASSWORD_LIFE_TIME과 PASSWORD_GRACE_TIME에만 신경쓰면 된다.

DEFAULT Profile의 PASSWORD_LIFE_TIME는 같은 패스워드를 인증에 사용할 수 있는 날 수를 정의한다.

PASSWORD_GRACE_TIME은 경고가 발생한 날부터 로그인이 가능한 유예 기간의 날 수를 정의한다.
패스워드가 유예 기간동안 변경되지 않는다면 패스워드는 소멸된다.

aaaa 사용자의 PASSWORD_GRACE_TIME 값은 7로 설정되어 있다.
그래서 ORA-28002 경고가 발생하지만 여전히 데이터베이스에 로그온 할 수가 있다.
유예기간 동안 패스워드를 변경하지 않는다면 패스워드는 소멸될 것이고 좀 더 지나면 접속이 거부될 것이다.
PASSWORD_GRACE_TIME 값을 설정하지 않는다면 UNLIMITED가 기본값이 되고 데이터베이스에서 경고는 발생하지만 사용자는 무기한으로 접속이 가능해진다.

보통 PASSWORD_LIFE_TIME이 계정이 생성된 날짜와 연관되어 있다고 잘못 해석한다. 실제로 PASSWORD_LIFE_TIME은 계정의 패스워드가 변경된 시간이나 패스워드가 변경되지 않았다면 계정이 만들어진 시간을 측정해서 Profile을 제한한다.

계정 생성 시간과 패스워드 변경 시간은 USER$.CTIME과 USER$.PTIME에서 볼 수 있다.

SQL> select ctime, ptime from sys.user$ where name = 'aaaa';

CTIME         PTIME
----------  -----------
14-OCT-07  14-OCT-07


dba_users 뷰에서도 계정이 생성된 시간을 볼 수 있다.

SQL> select created from dba_users where username = 'aaaa';

CREATED
----------
14-OCT-07


자.. 이제 현재 시간을 보자.

SQL> select sysdate from dual;

SYSDATE
----------
09-FEB-09


패스워드를 변경한 시간과 현재 시간의 간격이 PASSWORD_LIFE_TIME를 훌쩍 넘겨버렸다.
자 이제 PASSWORD_GRACE_TIME 설정에 따라 7일간만 aaaa 사용자로 데이터베이스에 접속할 수 있다. 물론 경고는 발생한다.



이 문제의 해결 방법
-----------------------
가. 패스워드를 바꾼다.
일시적으로 이 에러를 단지 피하길 원한다면 패스워드를 바꾸면 된다.


$ sqlplus aaa/bbb

SQL> password
Old password:
New password:
Retype new password:
Password changed
SQL> conn aaaa/ccc!12
Connected

이제 변경시간을 확인해보자.

SQL> select ctime, ptime from sys.user$ where name = 'aaaa';


CTIME         PTIME
----------  ----------
14-OCT-07  09-FEB-09


이건 일시적인 방법이고.. 180일 후에는 또 같은 메시지를 볼 수 있다.


나. 사용자의 Profile 중 PASSWORD_LIFE_TIME resource를 바꾼다.

aaaa사용자의 DEFAULT Profile 중 PASSWORD_LIFE_TIME resource를 변경하는 영구적인 방법.


SQL> select profile from dba_users where username = 'aaaa';


PROFILE
----------
DEFAULT


다음과 같이 처리하면 위의 에러를 다시는 보지 않을 것이다.


SQL> alter profile default limit PASSWORD_LIFE_TIME UNLIMITED;


Profile altered.

 

끝.


ps. 퍼갈 때는 댓글 남겨주시고. 출처 밝혀주시길.

http://refill.egloos.com/4841310

'ORACLE' 카테고리의 다른 글

EXISTS  (0) 2011.11.13
EXP시 SYS.DBMS_DEFER_IMPORT_INTERNAL 식별자 오류  (0) 2011.05.12
CentOS 5.5 ORACLE 11g 설치  (0) 2011.05.09
트리거  (0) 2010.02.24
2011. 5. 12. 02:12


sqlplus / as sysdba

grant execute on dbms_defer_import_internal to exp_full_database;

grant exp_full_database to test;

'ORACLE' 카테고리의 다른 글

EXISTS  (0) 2011.11.13
ORA-28002 : the password will expired within N days. 해결 방법  (0) 2011.06.15
CentOS 5.5 ORACLE 11g 설치  (0) 2011.05.09
트리거  (0) 2010.02.24
2011. 5. 9. 00:59


http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html

해당버전에 맞는 ORACLE 다운로드

필요한 패키지들을 설치

yum install 패키지명 이나 rpm 으로 설치

rmp - Uvh compat-libstdc++-33*
rmp - Uvh elfutils-libelf*
rmp - Uvh glibc-2.*
rmp - Uvh glibc-devel-2.*
rmp - Uvh glibc-common-2.*
rmp - Uvh glibc-headers-2.*
rmp - Uvh gcc-4.*
rmp - Uvh ksh*
rmp - Uvh libgcc-4.*
rmp - Uvh libaio-0.*
rmp - Uvh libaio-devel-0.*
rmp - Uvh libgomp-4.*
rmp - Uvh libstdc++-4.*
rmp - Uvh libstdc++-devel-4.*
rmp - Uvh unixODBC-2.*
rmp - Uvh unixODBC-devel-2.*
rmp - Uvh sysstat-7.*
rmp - Uvh binutils-2.*
rmp - Uvh make-3.*

su -
# groupadd oinstall
# groupadd dba
# useradd -g oinstall -G dba oracle
# passwd oracle
패스워드 설정 하고

# mkdir /oracle
# mkdir /oracle/11g
# chown -R oracle:oinstall /oracle
# chmod -R 775 /oracle

/oracle 디렉토리를 만들고 소유자를 oracle로 변경하여 퍼미션을 변경

#su - oracle
oracle 계정에 접속

#vi .bash_profile 입력하고 내용추가

export DISPLAY=:0.

ORACLE_HOSTNAME=localhost.localdomain; export ORACLE_HOSTNAME
ORACLE_BASE=/oracle/11g; export ORACLE_BASE
ORACLE_HOME=$ORACLE_BASE/product/11.2.0/db_1; export ORACLE_HOME
ORACLE_SID=ORCL; export ORACLE_SID
ORACLE_TERM=xterm; export ORACLE_TERM
PATH=/usr/sbin:$PATH; export PATH
PATH=$ORACLE_HOME/bin:$PATH; export PATH
LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib; export LD_LIBRARY_PATH
CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib; export CLASSPATH

SID는 오라클설치시 입력할 이름으로 작성

#su -
다시 루트계정으로 들어가 메모리정보를 수정
#vi /etc/sysctl.conf

kernel.shmmax = 536870912
kernel.shmall = 268435456
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default=4194304
net.core.rmem_max=4194304
net.core.wmem_default=262144
net.core.wmem_max=1048586
fs.aio-max-nr = 1048576
fs.file-max = 6815744

디폴트값보다 높아도 상관없음 오라클설치전 환경검사시 부족한 부분은 따로 늘려준다.

#/sbin/sysctl -p
정상등록되어 있는지 확인

재부팅을 한번 하고 (재부팅을 안해서 에러메세지가 발생했는데 왜그랬지는 모르겠다--; 재부팅하니 인스톨됨)

#su - oracle
오라클을 다운받은 경로로 이동하고
#./runinstaller


GUI 창이 열리면서 인스톨이 시작된다.


 




필요한 패키지와 변수가 실패뜨경우 인스톨진행중에 실패할 수있으므로 최대한 해결 후 다음으로 진행한다.

 


터미널창을 열고 루트계정으로 해당 스크립트를 실행


오라클 설치 완료

'ORACLE' 카테고리의 다른 글

EXISTS  (0) 2011.11.13
ORA-28002 : the password will expired within N days. 해결 방법  (0) 2011.06.15
EXP시 SYS.DBMS_DEFER_IMPORT_INTERNAL 식별자 오류  (0) 2011.05.12
트리거  (0) 2010.02.24
2010. 2. 24. 10:40

트리거 (TRIGGER) 란?

  • 간단히 말해 INSERT,UPDATE, DELETE 문이 Table 에 대하여 수행 되어질 때 묵시적으로 수행되는 Procedure 이다.
  • 트리거는 table 에 저장되는 것이 아니라 별도로 오라클 데이터베이스 자체에 저장 된다.
  • 트리거는 view 에 대해서는 동작하지 않고 table 자체에 대해서만 정의 될 수 있다.

 

트리거란 특정 테이블의 데이터에 변경이 가해졌을때 묵시적으로 자동으로 수행되는 저장 프로시져라 할 수 있다. C++ 언어 또는 Java 의 Class 의 경우 Constructor 와 Destructor 가 있다. 이들은 Class 가  만들어 질때 자동으로 호출되거나 아니면 소멸되기 전에 자동으로 호출되는 묵시적 수행 함수이다. 바로 이와 같은 기능이 트리거이다.

일반적으로 저장 프로시져 (Stored Procedure)는 사용자가 필요할 때 직접 수행시켜서 해당 프로시져를 수행하였다. 하지만 트리거는 이와 다르게 테이블에 INSERT, UPDATE, DELETE 문에 의하여 변경이 되어질 때 자동으로 수행되므로 이 기능을 이용하여 여러가지 작업을 할 수 있다. 트리거는 이와 같은 특성이 있기 때문에 사용자가 직접 호출 할 수는 없다.

 

image

 

INSERTED / DELETED 테이블

트리거를 잘 사용하기 위해서는 INSERTED 와 DELETED 라는 테이블을 이해 해야 한다. 다시 한번 읽어 보기 바란다. INSERT 와 DELETE 가 아니다. INSERTED 및 DELETED 이다. SQL의 INSERT , DELETE 구문이 아니라는 점을 알기 바란다.  이들은 둘다 테이블 이름이다.
INSERTED 테이블
DELETED 테이블

그럼 이 두가지의 테이블은 과연 무엇일까?? 이 두개의 테이블은 물리적으로 존재하는 테이블이 아니다. 그렇다면, 바로 논리적인 테이블로 그냥 임시 테이블이라 생각하면 좋을듯 하다.

특정 테이블의 데이터가 변경이 가해졌을때 트리거를 위해 자동으로 만들어지는 논리적인 가상의 테이블인 것이다. 그 이름에서 알 수 있듯이 INSERTED 테이블은 테이블에 새로운 데이터가 INSERT 될 때, DELETED 테이블은 테이블의 데이터가 삭제 될때 만들어 진다.

여기서 우리는 한가지 의문을 가진다, UPDATE 에 대한 테이블은 없는가?  하고... 이에 대한 해답은

UPDATE = DELETE + INSERT

이기 때문이다. 즉 변경된다는 것은 기존 값이 제거되고 새로운 값이 추가 되는 것으로 생각할 수 있기 때문이다.

즉 UPDATE 에 의한 테이블 변경은 INSERTED 및 DELETED 테이블이 동시에 존재 한다는 것을 의미 한다.

 

그러면 이 두개의 가상 테이블에는 어떠한 값이 존재할까?

DELETED 테이블에는 제거 되기 바로 전의 데이터 들이 있게되고 INSERED 테이블에는 변경되는 새로운 내용이 들어가게 된다.

* 이 두가지의 테이블은 말그대로 테이블이다. 그러므로 select * from DELETED ; 와 같이 사용할 수 있다는 것이다.

 

트리거 만들기

CREATE TRIGGER 문이 트리거를 만들어 주는 명령이다. 또한 DROP TRIGGER 를 이용하여 만들어진 트리거를 제거할 수도 있다. 또한 ALTER TRIGGER를 이용하여 기존의 트리거를 수정 할 수도 있다.

 

트리거를 만들때는 다음과 같은 내용을 포함하게 된다.

  • 트리거의 이름
  • 어느 테이블에 대한 트리거인지 테이블 이름 지정
  • INSERT,DELETE,UPDATE 중 어느 경우에 수행될 트리거인지 지정 (복수 선택이 가능하다)
  • 실제 수행될 쿼리문 : 이 쿼리문 안에서 INSERTED 및 DELETED 테이블을 이용할 수 있다.

 

트리거를 이용하여 어떤 작업이든 수행할 수는 없다.  트리거를 통하여 수행할 수 없는 작업들도 있다는 것이다. 수행할 수 없는 작업들은 다음과 같다.

  • 데이터베이스의 변경 : ALTER DATABASE
  • 데이터베이스의 생성 : CREATE DATABASE
  • 데이터베이스의 제거 : DROP DATABASE
  • 데이터베이스의 복구 : RESTORE DATABASE
  • 로그 복구 : RESTORE LOG
  • 기타(DISK INIT, DISK RESIZE, LOAD DATABASE, LOAD LOG, RECONFIGURE)

 

트리거를 어느때 사용하는가 를 살펴 보자.

  • 데이터베이스 테이블 생성하는 과정에서 참조 무결성과 데이터 무결성 등의 복잡한 제약 조건 생성하는 경우
  • 데이터베이스 테이블의 데이터에 생기는 작업의 감시, 보완
  • 데이터베이스 테이블에 생기는 변화에 따라 필요한 다른 프로그램을 실행하는 경우
  • 불필요한 트랜잭션을 금지하기 위해
  • 컬럼의 값을 자동으로 생성되도록 하는 경우
  • 복잡한 뷰를 생성하는 경우

 

 

트리거의 생성 문법 구조
CREATE [ OR REPLACE ] TRIGGER 트리거이름 BEFORE | AFTER | INSTED OF
Triggering_event ON 테이블이름
[ FOR EACH ROW ]
[ WHEN (조건식) ]
PL/SQL 블록;

 
좀더 정밀한 문법 구조...........
CREATE [OR REPLACE] TRIGGER [schema.]trigger
{BEFORE | AFTER}
{DELETE | INSERT | UPDATE [OF column [, column] ...]}
[OR {DELETE | INSERT | UPDATE [OF column [, column] ...]}] ...
ON [schema.]table
[ [REFERENCING { OLD [AS] old [NEW [AS] new]
| NEW [AS] new [OLD [AS] old] } ]
FOR EACH ROW
[WHEN (condition)] ]
pl/sql_block

트리거 요소들 설명

    CREATE [OR REPLACE] TRIGGER [schema.]trigger
      트리거 생성,재생성명령.
    BEFORE | AFTER
      트리거의 시작시점이 트랜잭션의 전인지 후인지를 나타냄.
    {DELETE | INSERT | UPDATE [OF column [, column] ...]}
      데이타의 처리유형
    [OR {DELETE | INSERT | UPDATE [OF column [, column] ...]}] ...
      트리거의 처리유형을 조합하여 선언할때 사용하는
    ON [schema.]table
      트리거가 INVOKE시킬 트랜잭션이 일어나는 테이블
    FOR EACH ROW : 트리거의 종류,
      FOR EACH ROW이면 Row-Level Trigger 이문구를 쓰지 않으면 Statement-Level Trigger
    [WHEN (condition)] ]
      데이타의 처리유형이외의 조건을 삽입할 경우에 사용
    pl/sql_block
      실제 트리거의 BODY부분.

 

 

 

트리거를 사용하기 위한 권한들
SYSTEM PRIVILEGE
변경할 테이블의 OWNER 권한.
alter table 권한.
ALTER ANY TABLE권한
CREATE TRIGGER권한.
CREATE ANY TRIGGER권한.
ALTER ANY TRIGGER 권한.
트리거 트랜잭션을 수행할 수 있는 권한.

 

이러한 트리거의 유형은 크게 두가지로 나뉜다. : 트리거의 유형
행수준 트리거(Row -Level Triggers) : 트랜잭션내의 각 행에 대해 한 번만 수행            
문수준 트리거(Statement-level Triggers): 트랜잭션내에서 한번만 수행

 

트리거의 발생 시점
이벤트의 전후에 트리거가 발생  
{BEFORE|AFTER} {INSERT|UPDATE|DELETE} {  row|statement}
2*3*2 총 12가지의 유형이 나올수 있다.

 

 

트리거의 삭제
DROP TRIGGER [schema.]trigger 
트리거가 데이터 딕셔너리에서 영구히 삭제된다.

트리거의 Enable / Disable

기본적으로 트리거를 생성함과 동시에 활성화가 되어 있다.      

ALTER TRIGGER [schema.]trigger
{ ENABLE | DISABLE | COMPILE }
    ENABLE : 트리거를 실행 할 수 있는 상태로 만든다. DISABLE : 트리거를 실행하지 못하는 상태로 만든다. COMPILE : 트리거를 재 컴파일 한다.
특정 테이블의 모든 트리거를 활성화, 비활성화 시킬 수 있다. ALTER TABLE [schema.]table_name [ENABLE|DISABLE] ALL TRIGGERS

 

흔히 사용하는 트리거 이름 기법 (작명 기법)

트리거의 명칭은 적용될 테이블, 기동하는 DML명령, 
전후(before/after)상태, row-level인지 아닌지 명확하게 표시하는게 좋다.
ledger_def_upd_row
ledger_aft_upd_ins_row 등등.

 

트리거의 조합에 따라서 INSERTING, UPDATING, DELETING의 세가지로 비교할 수 있다.
INSERTING : 트리거링 문장이 INSERT일때 TRUE 그렇지 않으면 FALSE
UPDATING : 트리거링 문장이 UPDATE일때 TRUE 그렇지 않으면 FALSE
DELETING : 트리거링 문장이 DELETE일때 TRUE 그렇지 않으면 FALSE

 

 

image

image

'ORACLE' 카테고리의 다른 글

EXISTS  (0) 2011.11.13
ORA-28002 : the password will expired within N days. 해결 방법  (0) 2011.06.15
EXP시 SYS.DBMS_DEFER_IMPORT_INTERNAL 식별자 오류  (0) 2011.05.12
CentOS 5.5 ORACLE 11g 설치  (0) 2011.05.09
prev"" #1 next