검색결과 리스트
분류 전체보기에 해당되는 글 93건
- 2011.04.25 [Oracle] ROWNUM 사용 시 주의
- 2011.04.22 오라클 데이터 타입
- 2011.04.22 오라클 DECODE
- 2011.04.22 인덱스의 정의
- 2011.04.22 [ORACLE] 데이터베이스 시작의 3단계 설명
글
똑같은 query를 다른 두 시스템에서 실행했다. 헌데 그 결과는 완전 정반대.. 이런 어처구니 없는 경우가 있을 수가.. 아주 황당했다. (사실은 query가 바보였음 -ㅅ-)
(실제 테이블을 내용을 쓸 수 없으니 살짝 테이블 이름과 내용을 바꿔서..) 내가 원하는 결과는 사용자 테이블과 로그인한 시간, IP 등을 기록하는 테이블을 조인해서.. 가장 최근의 기록 1개를 얻고 싶다.
FROM (SELECT U.USER_ID, H.LOGIN_TIME, ROWNUM AS RNUM
FROM USER U, LOGIN_HIST H
WHERE U.USER_ID = H.USER_ID
ORDER BY H.LOGIN_TIME DESC
AND u.user_name = '바보') SUB
WHERE RNUM = 1;
자.. 이 query의 문제는 뭘까?? 사실 이 문제가 발생하기 전 까지는 누가 만들어 놓은건지도 궁금하지 않았던 저 구석에 있던 query인데.. 문제는 이렇게 발생했다. 다음은 동일한 데이터를 가진 두 서버에서 실행한 이 query의 결과이다.
USER_ID | LOGIN_TIME
--------+-----------
test1 | 2010-10-10 10:10:10
2번 서버
USER_ID | LOGIN_TIME
--------+-----------
test1 | 2010-10-05 10:10:10
왜 이런 결과가 나온걸까?? 우선 가장 바깥에 있는 select 문을 벗겨서 subquery 부분만 실행해 봤다. 그랬더니 이런 결과가 나오는 것이 아닌가??
USER_ID | LOGIN_TIME | RNUM
--------+------------+-----
test1 | 2010-10-10 10:10:10 | 1
test1 | 2010-10-09 10:10:10 | 2
test1 | 2010-10-07 10:10:10 | 3
test1 | 2010-10-05 10:10:10 | 4
2번 서버
USER_ID | LOGIN_TIME | RNUM
--------+------------+-----
test1 | 2010-10-10 10:10:10 | 4
test1 | 2010-10-09 10:10:10 | 3
test1 | 2010-10-07 10:10:10 | 2
test1 | 2010-10-05 10:10:10 | 1
아니!! 같은 query인데 RNUM이 정반대로 붙어있는게 아닌가?? 정말 귀신이 곡할 노릇이라고 하면서 검색을 시작.. 흠.. 검색 시작한지 2분도 안돼서 답 발견 @ㅅ@
역시 문제는 ROWNUM이었다. ROWNUM의 동작 원리를 알지 못 한 상태에서 query를 만드니 저런 query가 만들어진 것 같다. 일단, ROWNUM은 select된 결과 집합에 대한 가상 순번이다. 이 번호는 DB에서 꺼내지는 순서대로 붙게 된다. (optimizer가 어떻게 동작하는지에 따라 그 순서는 달라질 수 있다.) 그리고 결정적으로 잘못 생각한 것은 ORDER BY 구문.. ORDER BY는 결과 집합이 생성된 후에 적용되는 조건이다.
이 두 동작 원리를 가지고 다시 문제를 짚어보자. 내가 원하는 것은 해당 이름의 사용자가 가장 최근에 로그인한 시간을 알고 싶은 것이다. 다시 말해 먼저 로그인한 시간으로 정렬한 후 번호를 붙여서 가장 최근 정보를 가져오는 순서다. 헌데.. ROWNUM과 ORDER BY를 하나의 SELECT문에 넣게 되면서 그 적용 순서가 의도와는 다르게 뒤바뀌게 된 것이다. 결과 집합을 꺼내오면서 ROWNUM이 먼저 적용되고, 모든 결과 집합이 모인 후에 정렬이 된 것이다. 오라클의 optimizer가 동작하는 경우에 따라서 결과 집합을 만드는 순서가 바뀔 수 있고 위의 두 서버와 같이 정반대의 결과가 나올 수도 있는 것이다.
사실 이 query는 이런 원리를 알고 보면 다음과 같이 수정해면 간단하게 원하는 결과를 얻을 수 있는 것이다. 처음부터 왜 저렇게 ROWNUM을 붙였는지 잘 모르게뜸 @ㅅ@
FROM (SELECT U.USER_ID, H.LOGIN_TIME
--, ROWNUM AS RNUM 이 분분은 사실 필요 없기 때문에 제거
FROM USER U, LOGIN_HIST H
WHERE U.USER_ID = H.USER_ID
ORDER BY H.LOGIN_TIME DESC
AND u.user_name = '바보') SUB
WHERE ROWNUM = 1;
'먹고살기 > Oracle' 카테고리의 다른 글
SQL _ HAVING_2 (0) | 2011.04.29 |
---|---|
SQL _ CASE식 (0) | 2011.04.29 |
오라클 데이터 타입 (0) | 2011.04.22 |
오라클 DECODE (0) | 2011.04.22 |
인덱스의 정의 (0) | 2011.04.22 |
설정
트랙백
댓글
글
이 름 |
최대 길이 |
타 입 |
설 명 |
---|---|---|---|
CHAR |
2000 byte |
문자열 |
고정 길이 |
NCHAR |
2000 byte |
문자열 |
다국적 언어 지원 |
VARCHAR2 |
4000 byte |
문자열 |
가변 길이 |
NVARCHAR2 |
4000 byte |
문자열 |
가변 길이, 다국적 언어 지원 |
LONG |
2 Gb |
문자열 |
가변 길이 |
RAW |
2 Gb |
바이트 문자열 |
가변 길이 |
LONG RAW |
2 Gb |
이진 문자열 |
|
NUMBER |
10^-38 ~ 10^38 |
숫자 |
|
DATE |
날짜 |
BC 4712/1/1 ~ CE 4712/12/31 | |
BLOB |
4 Gb |
이진 데이터 |
구조화 되지 않은 데이터 |
CLOB |
4 Gb |
문자 데이터 |
구조화 되지 않은 데이터 |
NCLOB |
4 Gb |
문자 데이터 |
다국적 언어 지원 |
BFILE |
4 Gb |
이진 데이터 |
데이터베이스 외부에 데이터를 저장함 |
ROWID |
10 byte |
이진 데이터 |
로우 어드레스 |
ROWID |
4000 byte |
이진 데이터 |
로우 어드레스 |
ANSI/ISO SQL 타입과의 비교
ANSI/ISO SQL 데이터 타입 |
오라클 데이터 타입 |
---|---|
CHARACTER(n), CHAR(n) |
CHAR(n) |
NUMERIC(p,s), DECIMAL(p,s), DEC(p,s) |
NUMBER(p,s) |
INTEGER, INT, SMALLINT |
NUMBER(38) |
FLOAT(p) |
FLOAT(p), NUMBER |
REAL |
FLOAT(63), NUMBER |
DOUBLE PRECISION |
FLOAT(126), NUMBER |
CHARACTER VARYING(n), CHAR VARYING(n) |
VARCHAR2(n) |
SQL/DS, DB2 데이터 타입과 비교
SQL/DS, DB2 데이터 타입 |
오라클 데이터 타입 |
---|---|
CHARACTER(n) |
CAHR(n) |
VARCHAR(n) |
VARCHAR2(n) |
LONG VARCHAR |
LONG |
DECIMAL(p,s) |
NUMBER(p,s) |
INTEGER, SMALLINT |
NUMBER(38) |
FLOAT(p) |
FLOAT(p), NUMBER |
DATE |
DATE |
SQL/DS, DB2 데이터 타입 중 TIME, TIMESTAMP, GRAPHIC, VARGRAPHIC, LONG VARGRAPHIC들은
오라클 데이터 타입과 대칭되는 것이 없다.
[출처] 오라클 데이터 타입|작성자 하늘아이
'먹고살기 > Oracle' 카테고리의 다른 글
SQL _ CASE식 (0) | 2011.04.29 |
---|---|
[Oracle] ROWNUM 사용 시 주의 (0) | 2011.04.25 |
오라클 DECODE (0) | 2011.04.22 |
인덱스의 정의 (0) | 2011.04.22 |
[ORACLE] 데이터베이스 시작의 3단계 설명 (0) | 2011.04.22 |
설정
트랙백
댓글
글
DECODE
프로그래밍언어의 스위치 문과 같은 기능을 하는 SQL 함수이다.
- 형식
DECODE (비교값 , CASE1 , 결과 1 , CASE2 , 결과 2 , CASE3 , 결과 3..... , 기본값)
|
- 주의사항
비교값 과 CASE 값의 데이터 타입이 같아야 한다.
다를 경우에는 자동형변환이 되면 문제없지만 자동형변환이 불가능할 경우 오류를 발생한다.
※ 오라클이 알아서 비교값을 CASE 값과 같은 타입으로 변환시키려고 시도한다.
※ DECODE함수
- 특정 컬럼의 값을 기준으로 마치 IF문을 사용하는 것과 같은 효과를 내는 함수
- 해당 컬럼의 값이 'A'이면 지정한 특정한 값을 출력하고, 'B'이면 또 다른 값을 출력
- 기본값을 정해서 조건을 만족하지 않는 경우의 출력 제어 가능
- 구문
DECODE({column | expression}, search1, result1 [,search2,result2] ...
[,default] )
- 사용 예
① job값에 따른 새로운 직업명 출력② deptno에 따른 인상급여 출력
[출처] 오라클 DECODE|작성자 하늘아이
'먹고살기 > Oracle' 카테고리의 다른 글
[Oracle] ROWNUM 사용 시 주의 (0) | 2011.04.25 |
---|---|
오라클 데이터 타입 (0) | 2011.04.22 |
인덱스의 정의 (0) | 2011.04.22 |
[ORACLE] 데이터베이스 시작의 3단계 설명 (0) | 2011.04.22 |
오라클 변환함수 ( TO_CHAR ) (0) | 2011.04.22 |
설정
트랙백
댓글
글
※ 인덱스란?
인덱스는 테이블이나 클러스트에서 쓰여지는 선택적인 객체로서, 오라클 데이터베이스 테이블내의
원하는 레코드를 빠르게 찾아갈 수 있도록 만들어진 데이터 구조입니다.
자동 인덱스 : 프라이머리 키 또는 uinque 제한 규칙에 의해 자동적으로 생성되는 인덱스 입니다. |
※ Index를 생성하는 것이 좋은 Column |
※ 오라클 인덱스는 B-tree(binary search tree)에 대한 원리를 기반으로 하고 있습니다. |
|
SQL>CREATE BITMAP INDEX emp_deptno_indx |
|
SQL>CREATE UNIQUE INDEX emp_ename_indx |
|
SQL>CREATE INDEX dept_dname_indx |
|
SQL>CREATE UNIQUE INDEX emp_empno_ename_indx |
※ 인덱스의 삭제 |
※ 인덱스에 대한 정보는 USER_INDEXES 뷰 또는 USER_IND_COLUMNS뷰를 통해 검색할 수 |
'먹고살기 > Oracle' 카테고리의 다른 글
오라클 데이터 타입 (0) | 2011.04.22 |
---|---|
오라클 DECODE (0) | 2011.04.22 |
[ORACLE] 데이터베이스 시작의 3단계 설명 (0) | 2011.04.22 |
오라클 변환함수 ( TO_CHAR ) (0) | 2011.04.22 |
오라클 접속 리스너 설정하기.(tnanames.ora 설정) (0) | 2011.04.22 |
설정
트랙백
댓글
글
1-1. NOMOUNT
- 인스턴스가 메모리에 할당 및 시작되는 단계이다.
- 데이터베이스 관리에 있어서 데이터베이스 생성 또는 컨트롤 파일을 생성하는 작업은 NOMOUNT 단계에서만 할 수 있다.
1-2. MOUNT
- 컨트롤 파일을 읽고 데이터베이스를 마운트하는 단계이다.
- MOUNT 단계에서만 할 수 있는 작업
1) 데이터 파일의 이름 변경
2) 아카이브, 노아카이브 모드 변경
3) 전체 데이터베이스 복구
1-3. OPEN
- 데이터베이스를 시작하고 사용자들의 접속을 허용하는 단계이다.
- 만약, OPEN 단계에서 데이터 파일 또는 리두 로그 파일이 실제 존재하지 않으면 오라클 서버는 오류를 발생시키고 데이터베이스는 MOUNT 단계에서 멈추게 된다.
-------------------------------------------------------------------
2. ALTER DATABASE
데이터베이스가 NOMOUNT or MOUNT 단계에 있을때 상위단계로 가기 위해서는 ALTER DATABASE 명령을 사용해야 한다.
하지만 상위단계로만 이동이 가능할 뿐 하위단계로의 이동은 불가능하다.
SQL> shutdown
데이터베이스가 닫혔습니다.
데이터베이스가 마운트 해제되었습니다.
ORACLE 인스턴스가 종료되었습니다.
SQL> startup nomount - 데이터베이스가 시작되었지만 nomount 상태이다.
ORACLE 인스턴스가 시작되었습니다.
Total System Global Area 135338868 bytes
Fixed Size 453492 bytes
Variable Size 109051904 bytes
Database Buffers 25165824 bytes
Redo Buffers 667648 bytes
SQL> alter database mount; - alter database 명령을 이용해서 상위단계인 MOUNT 단계로 상승시킨다.
데이타베이스가 변경되었습니다.
SQL> alter database open; - alter database 명령을 이용해서 상위단계인 OPEN 단계로 상승시킨다.
데이타베이스가 변경되었습니다.
SQL> shutdown
데이터베이스가 닫혔습니다.
데이터베이스가 마운트 해제되었습니다.
ORACLE 인스턴스가 종료되었습니다.
SQL>
-------------------------------------------------------------------
3. RESTRICT 모드
데이터베이스를 RESTRICT 모드로 오픈하고 RESTRICTED SESSION 권한을 보유한 사용자들만이 접속할 수 있도록 하는 방법
SQL> startup restrict - RESTRICT 모드로 데이터베이스를 오픈 한다. 이때 RESTRICT는 데이터베이스의 접속에 대한 모든 사용자를 제한하는 명령어이다.
ORACLE 인스턴스가 시작되었습니다.
Total System Global Area 135338868 bytes
Fixed Size 453492 bytes
Variable Size 109051904 bytes
Database Buffers 25165824 bytes
Redo Buffers 667648 bytes
데이터베이스가 마운트되었습니다.
데이터베이스가 열렸습니다.
SQL> conn scott/tiger - SCOTT 계정으로 접속하려고 하지만 RESTRICTED SESSION 권한이 없기 때문에 접속이 안된다.
ERROR:
ORA-01035: ORACLE only available to users with RESTRICTED SESSION privilege
경고: 이제는 ORACLE에 연결되어 있지 않습니다.
SQL> conn /as sysdba - RESTRICTED SESSION 권한을 주기 위해 관리자로 접속한다.
연결되었습니다.
SQL> grant restricted session to scott; - RESTRICTED SESSION 권한 부여
권한이 부여되었습니다.
SQL> conn scott/tiger
연결되었습니다.
SQL> conn /as sysdba
연결되었습니다.
SQL> revoke restricted session from scott; - RESTRICTED SESSION 권한을 취소한다.
권한이 취소되었습니다.
SQL> startup force - RESTRICT 명령어를 풀어주려면 force 명령어를 통하여 재시작해주면 된다.
ORACLE 인스턴스가 시작되었습니다.
Total System Global Area 135338868 bytes
Fixed Size 453492 bytes
Variable Size 109051904 bytes
Database Buffers 25165824 bytes
Redo Buffers 667648 bytes
데이터베이스가 마운트되었습니다.
데이터베이스가 열렸습니다.
-------------------------------------------------------------------
4. ALTER SYSTEM 명령을 이용한 사용자의 접속을 강제로 종료
SQL> select sid, serial# from v$session - 데이터베이스에 연결되어 있는 사용자를 확인한다.
2 where username='SCOTT';
선택된 레코드가 없습니다.
-------------------------------------------------------------------
스캇 세션
시작 \프로그램\Oracle - OraHome92\Application Development\sqlplus 실행 -> 스캇 계정으로 로그인
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
BONUS TABLE
DEPT TABLE
EMP TABLE
SALGRADE TABLE
-------------------------------------------------------------------
SQL> select sid, serial# from v$session
2 where username='SCOTT';
SID SERIAL#
---------- ----------
10 8
SQL> alter system kill session '10,8'; - KILL 명령어를 통해 session을 종료시킨다.
시스템이 변경되었습니다.
SQL> select sid, serial# from v$session
2 where username='SCOTT';
SID SERIAL#
---------- ----------
10 8
-------------------------------------------------------------------
스캇 세션
SQL> select * from tab;
select * from tab
*
1행에 오류:
ORA-00028: 세션이 종료되었습니다
[출처] [ORACLE] 데이터베이스 시작의 3단계 설명|작성자 하늘아이
'먹고살기 > Oracle' 카테고리의 다른 글
오라클 DECODE (0) | 2011.04.22 |
---|---|
인덱스의 정의 (0) | 2011.04.22 |
오라클 변환함수 ( TO_CHAR ) (0) | 2011.04.22 |
오라클 접속 리스너 설정하기.(tnanames.ora 설정) (0) | 2011.04.22 |
오라클 메모리 (0) | 2011.04.22 |
RECENT COMMENT