이 망할 놈의 오라클은 LIMIT이 지원되지 않습니다.
LIMIT이 얼마나 편한데!!!
오라클에서 LIMIT과 같은 기능이 필요했습니다.

ROWNUM이라는 것을 알게 되었는데, SELECT를 하게 된 결과에 자동으로 처음부터 끝까지 1부터 숫자를 매겨주는 듯했습니다. 아, 그래서 만약에 10번째꺼부터 20번째꺼를 추출해봐야지 라고 이런 쿼리를 날려봤습니다.

[code]SELECT * FROM BIZLIST WHERE ROWNUM >= 10 AND ROWNUM <= 20[/code]
이렇게 하니까 아무것도 안나오더라구요.
이게 안돌아가는 이유는 ROWNUM이라는 놈이 가상 칼럼이랍니다. 그래서 만약 칼럼이 SELECT될 때 10개가 출력되야하는 상황이라면 첫번째꺼 출력하고 ROWNUM을 붙이고, 두번째꺼 출력하고 ROWNUM을 붙이고, 그러다보니 저 조건에 맞지 않게 됩니다.

첫번째 출력될 놈은 ROWNUM이 1인데, 저 조건에 부합하지 않습니다. 그래서 출력이 안되고, 10번째 출력될 놈도 출력하려고 보니 다 조건에 맞지않아요. 그러다보니 차례대로 다 안나옵니다-_-;

즉 조건에 부합한 놈이 출력되고 난다음에 ROWNUM을 붙여줍니다.
그래서 ROWNUM이 10을 1로 바꿔버리면 ROWNUM이 1인놈부터 20개까지는 출력이 되는것이죠.

제가 설명을 좀 못하니 여기를 참조 하세요 ^^
http://www.oracle.com/technology/global/kr/oramag/oracle/06-sep/o56asktom.html

저걸 악(?) 이용하면 LIMIT처럼 구현할 수 있습니다-_-;
[code]SELECT * FROM (SELECT ROWNUM RNUM, BIZLIST.* FROM BIZLIST WHERE STATUS = 'A') A
WHERE A.RNUM BETWEEN 10 AND 20[/code]
쿼리를 잘 보시면 A테이블을 서브쿼리를 날려서 만들어줍니다. 즉 우리가 10~20까지 추출해야할 데이터를 다 추출해서 A라는 테이블을 만듭니다. 여기서 A테이블을 보면 ROWNUM도 칼럼에 추가를 시킵니다. RNUM이라는 이름으로!
그다음 이 추출된 모든 것이 보면 ROWNUM도 다 붙어있습니다. 그래서 이걸 다시 SELECT해서 RNUM이 10과 20사이인 것을 추출하게 하면 되는것이죠.
A테이블에서 WHERE절은 원하는 조건이니 없어도 되는 것이고-_-;
별 것도 아닌데 거창하게 써 놓은 이유는 제가 이것 때문에 반나절을 고생해서 입니다-_-;
아놔....ㅠㅠ

 
Posted by 머드초보
,
 
Toad나 GOLDEN32를 사용하기 위해서는 오라클 클라이언트를 설치해야하는데 이걸 설치하고 GOLDEN32로 접속해서 쿼리를 날려서 검색하면 한글이 나와야 하는 부분이 ???로 나오게 됩니다.

사용자 삽입 이미지

원래 2008년 7월 12일 이라고 나와야하는데-_-; 안 나옵니다.
이게 서버쪽 케릭터셋이랑 클라이언트 케릭터셋이 안맞아서 그런데요. 서버는 한글이 된다면 KOREAN_KOREA.KO16KSC5601이걸로 되어있을껍니다-_-; 저도 오라클은 잘 모르지만 이게 맞는 것 같습니다.
그래서 클라이언트쪽에도 맞춰줘야합니다.

윈도우에 설치하셨다면 NLS_LANG을 추가하면 됩니다. 어디다가 하냐면 레지스트리에다가 합니다.
시작 -> 실행 -> regedit 실행

HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE
여기로 찾아가서 ORACLE에 오른쪽 버튼 누르고, 새로만들기 -> 문자열값 하고
NLS_LANG이라고 씁시다.
더블클릭해서 값을 KOREAN_KOREA.KO16KSC5601이라고 합시다.

시도는 안해봤는데 환경변수로 지정해도 될 듯 합니다.
NLS_LANG=KOREAN_KOREA.KO16KSC5601



사용자 삽입 이미지
오....한글이 나와요!!!!


 
Posted by 머드초보
,
 
오라클 10G R2부터 TDE라는 기능을 제공합니다.
(참고로 Enterprise 이상의 버전에서만 됩니다. Oracle XE를 설치했는데 안되서 삽질했었습니다-_-)

말그대로 Transparent(투명한) Database Encryption(데이터베이스 암호화) 입니다-_-;
투명하다는 얘기는 암호화가 투명하게 되었다는 얘기인데요.
암호화가 되어서 DATABASE에 저장이 되지만, 암호화가 됐는지 확인 하는 방법은 며느리도 모릅니다.
해당 계정의 사용자는 데이터를 다 볼 수 있어야하니깐요 ^^
데이터베이스를 도난당했을 때 해당계정의 비밀번호를 모르는 이상 데이터베이스를 확인 할 수 없는 것 같습니다.
즉, SQL Injection같이 Application 단에서 발생하는 해킹은....소용없다는 얘기죠.

장점이 있다면 어플리케이션을 변경하지 않아도, 데이터베이스를 암호화 할 수 있습니다.

어쨌든 암호화가 필요해서 체험해봤습니다.
우선 ORACLE 10g이 필요하죠.

전자지갑을 생성해야합니다.
cd $ORACLE_HOME/network/admin
sqlnet.ora파일을 편집해서 아래와 같은 내용을 넣습니다.
ENCRYPTION_WALLET_LOCATION=
  (SOURCE=(METHOD=FILE)(METHOD_DATA=
   (DIRECTORY=/export/home/oracle/oracle/product/10.2.0/db_2/)))

전자지갑 저장소를 설정하는 듯하네요.

이제 오라클에 접속해봅시다.
-bash-3.00$ sqlplus /nolog

SQL*Plus: Release 10.2.0.2.0 - Production on Wed Jul 16 16:57:08 2008

Copyright (c) 1982, 2005, Oracle.  All Rights Reserved.

SQL> connect / as sysdba
Connected.
SQL> alter system set key identified by "welcome1";

System altered.

SQL>

이게 마스터키를 생성하는 부분인데요. 마스터키는 단 한번만 생성되어야 한다고 합니다. 다시 생성하게 되면 기존에 암호화 되어있던 데이터를 다시 암호화 해야한다는군요. 무슨 얘기지-_-;

저거대로 따라할라니까 힘들어서-_-; 그냥 insert해서 로그에 안찍히는 것만 보여주도록 해봅시다-_-;
Oracle LogMiner라는 놈을 이용해서 로그를 볼 수 있는데 이놈은 암호화된 데이터를 지원하지 않습니다. 그래서 암호화된 데이터는 보여지지가 않습니다.

테이블을 생성해봅시다.

connect oe/oe
create table cust_payment_info 
(first_name varchar2(11),
last_name varchar2(10),
order_number number(5),
credit_card_number varchar2(16) ENCRYPT NO SALT,
active_card varchar2(3));

Table created.
자세히 보면 credit_card_number 부분에만 ENCRYPT NO SALT라는 것을 적용했네요.
이렇게 해버리면 테이블 구조만 바꾸면서 암호화를 할 수 있습니다. 이미 만들어진 어플리케이션은 손대지 않아도 됩니다. 8i에서 제공하는 방법이 찾아보니까 있었는데 그건 키테이블을 따로 만들어서 데이터를 암호화시킨 상태에서 저장해버립니다. 나중에 데이터를 가져올 때 복호화 하고 그런식으로 하더라구요. 그거나 이거나 암호화해서 저장되는 법은 똑같습니다.

데이터를 insert해봅시다.
예제에는 조낸 많이 삽입하는데 조낸 귀찮으니까 1개만 삽입해봅시다-_-;
SQL> insert into cust_payment_info values
  2    ('Jon', 'Oldfield', 10001, '5446959708812985','YES');

1 row created.

SQL>

또 예제에서는 뭔가 삽질을 하는데 귀찮으니까 바로 로그확인에 들어갑시다-_-;
oradata에 있는 redo01~3으로 설정해주어야합니다.
SQL> connect / as sysdba;
Connected.
SQL> alter database add supplemental log data;

Database altered.

SQL> REM select member as LOG_FILE_LOCATION from v$logfile;
SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE ('/export/home/oracle/oradata/orcl/redo03.log', DBMS_LOGMNR.NEW);

PL/SQL procedure successfully completed.

SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE ('/export/home/oracle/oradata/orcl/redo02.log', DBMS_LOGMNR.ADDFILE);

PL/SQL procedure successfully completed.

SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE ('/export/home/oracle/oradata/orcl/redo01.log', DBMS_LOGMNR.ADDFILE);

PL/SQL procedure successfully completed.

SQL> EXECUTE DBMS_LOGMNR.START_LOGMNR (options => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + DBMS_LOGMNR.COMMITTED_DATA_ONLY);

PL/SQL procedure successfully completed.

SQL> select sql_redo from v$logmnr_contents where
  2  table_name = 'CUST_PAYMENT_INFO' and operation='INSERT';

SQL_REDO
--------------------------------------------------------------------------------
insert into "OE"."CUST_PAYMENT_INFO"("FIRST_NAME","LAST_NAME","ORDER_NUMBER","CR
EDIT_CARD_NUMBER","ACTIVE_CARD") values ('Jon','Oldfield','10001',Unsupported Ty
pe,'YES');


SQL>

결과에 암호화된 칼럼은 Unsupported Type이라고 뜨는군요.
잘은 모르지만 암호화가 된 듯 합니다.

암튼 손쉽게 암호화 할 수 있게 해놨군요.
어플리케이션에 손대지 않는 방법을 찾다가 이짓까지 삽질해보는군요.
 
Posted by 머드초보
,
 
오라클의 TDE기능을 체험하기 위해-_-; 마땅한 테스트 서버도 없고 해서 솔라리스를 설치해서 오라클을 설치해봤습니다.
2번만에 성공했습니다.

http://www.solanara.net/
여기는 윈디하나의 솔라나라인데, 여기에 너무 정리를 잘 해놔서 설치하는데 무리가 없었습니다.

저는 1번 실패하게 된 것이 SWAP공간이 없어서 실패를 했습니다.
swap공간은 이 분 블로그를 보고 참조했습니다.
http://akmamb.tistory.com/108

그 설치할 때 패키지가 있는지, 공간이 있는지 검사하는 부분이 있는데 저는 swap공간 부족과 SUNWi1cs랑 SUNWi15cs패키지가 없어서 경고를 먹었는데 두개 패키지는 설치하고 swap공간은 그냥 생까고 진행했더니 아놔 안되려면 처음부터 안되던가-_-; 설치하다가 데이터베이스를 생성하는 도중에 메모리가 딸리다면서 안됩니다-_-;

swap공간 늘리고 설치하면 완전 잘돼요 ^^

그리고, 또 걸렸던 것이!
서버 시작과 동시에 자동으로 실행되게 하려고 했는데 $ORACLE_HOME/bin/dbstart 스크립트가 안먹히는 겁니다-_-; 그래서 또 검색해보니-_-;
/var/opt/oracle/oratab 파일이 있는데, 이 놈의 맨 끝이 N으로 되어있습니다.
orcl:/export/home/oracle/oracle/product/10.2.0/db_2:Y

이걸 Y로 바꿔주니 rc3.d에 등록하니 잘 되더라구요.

실행스크립트는 그냥 이렇게-_-;
#!/bin/sh

case "$1" in
        start)
                echo -n "Starting oracle: "
                su - oracle dbstart /export/home/oracle/oracle/product/10.2.0/db_2
                echo
                ;;
        stop)
                echo -n "Shutting down oracle: "
                su - oracle dbshut /export/home/oracle/oracle/product/10.2.0/db_2
                echo
                ;;
esac
exit 0 

참고로 ORACLE_HOME이 oracle계정에 선언이 되어야겠죠? ORACLE_SID 등도 설정 되어야할 겁니다.
그건 윈디하나의 솔라나라에서 보고 따라하시면 돼요 ^^


PS. 윈디하나의 솔라나라에 좋은 자료가 많군요! 앞으로 자주 애용해야겠습니다 ^^

 
Posted by 머드초보
,
 
Oracle XE에서는 기본적으로 APEX를 제공합니다.
웹으로 db를 컨트롤할 수 있는 웹애플리케이션입니다. phpmyadmin같은 거죠.
그런데 이 apex가 디폴트로는 설치된 컴퓨터에서만 접속이 가능합니다.
http://www.oracle.com/technology/global/kr/products/database/application_express/html/apex_and_xe.html
여기에서 5번 항목을 보면,
5. Oracle APEX는 기본적으로 Oracle Database XE가 설치된 컴퓨터에서만 접근이 가능합니다. 관리자는 Database Home Page에서 원격 사용자의 접근을 활성화할 수 있습니다.
라고 되어있습니다.
저기서 원격 사용자의 접근을 활성화하는 것은 apex에서 해야한다는 얘기인데....-_-;
X-Window가 안깔린 리눅스에서 설치를 해버리니 apex에 접속할 수가 없습니다.
리눅스에서 netstat -an 해보면
tcp        0      0 127.0.0.1:8081          0.0.0.0:*               LISTEN
이렇게 되어있습니다.
즉 로컬에서만 접속되도록 8081이 오픈이 되어있네요.

리눅스에 웹브라우저가 설치가 되어있다면, system계정으로 로그인해서
관리 -> http엑세스관리 -> "로컬 서버와 원격 클라이언트에서 사용할 수 있음" 선택 확인.
하면 됩니다.

리눅스에 웹브라우저가 없다면 sqlplus로 직접 접속해서 설정을 변경할 수 있습니다.
root@ubuntu:~# sqlplus

SQL*Plus: Release 10.2.0.1.0 - Production on 목 7월 3 22:11:29 2008

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

사용자명 입력: system
암호 입력:

다음에 접속됨:
Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production
SQL> EXEC DBMS_XDB.SETLISTENERLOCALACCESS(FALSE);

PL/SQL 처리가 정상적으로 완료되었습니다.

SQL>
저렇게 설정하면 외부에서 접근이 가능합니다.

netstat -an하면
tcp        0      0 0.0.0.0:8081            0.0.0.0:*               LISTEN
아이피가 변경이 되어있네요 ^^

 
Posted by 머드초보
,