달력

4

« 2024/4 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
2011. 12. 1. 10:32

[ORACLE] Oracle Index 정리 Enjoy/ORACLE2011. 12. 1. 10:32


출처 : http://zetswing.com/bbs/board.php?bo_table=ORACLE_TIP&wr_id=4&page=3


※ 인덱스생성 명령을 실행하면 해당 테이블에 테이블락이 자동으로 걸린다.

그래서 서비스상태에서는 인덱스를 주면 장애가 날수 있습니다.

 

Index 정의

 

1) 조회속도를 향상시키기 위한 데이터베이스 검색 기술

 

2) 색인이라는 뜻으로 해당 테이블의 조회결과를 빠르게 하기 위해 사용합니다.

보통 INDEX를 테이블의 특정 컬럼에 한개이상을 주게 되면 Index table 이 따로 만들지는데

이 INDEX table 에는 인덱스컬럼의 로우의 값과 rowid 값이 저장되게 되며 로우의값은 정렬된 B-TREE 구조로 저장시켜두어 검색시 좀더 빠르게 해당 데이타를 찾는데 도움을 준다.

하지만 UPDATE,INSERT,DELETE 시에 속도가 느려진다는 단점이 있다.

왜냐하면 INSERT, UPDATE, DELETE 시에는 원본TABLE은 물론 INDEX table 에도 데이타를 갱신시켜 주어야 하기 때문입니다.

하지만 너무 작은 로우(레코드)가 있는 TABLE에 INDEX를 사용하게 되면 index의 효력을 제대로 발휘못하며 반드시 INDEX키를 조건으로 검색시에는 연산이나 가공을 하면 INDEX를 탈수없다.

 

※ 테이블을 생성하고 컬럼을 만든후 데이타를 삽입하면 하나의 로우가 생성되며 이 로우는 절대적인 주소를 가지게 됩니다. 이 절대적인 주소를 ROWID 라고 합니다.

 

INDEX가 필요한 이유?

 

조회 속도를 최대한 줄일수 있다.

 

참고

인덱스를 만들 때 현재 컬럼수가 너무 많으면 DML의 성능이 떨어지고 너무 부족하면

쿼리의 성능이 떨어집니다. 데이터가 많고 B*Tree Index인 경우 컬럼level이 하나

늘어날 때 그에 따른 node의 추가가 엄청나게 일어날 수 있습니다

이런 node들이 너무 많으면 쿼리성능도 좋을 수 없습니다.

인덱스는 일반적으로 최대 5개 컬럼 내외정도로 상황에 따라 합리적으로 구성합니다.

인덱스(Index)가 필요한 경우

1. 데이타가 많이 쌓일거라고 예상되는 경우와 많이 쌓인 경우와 현재 화면에서 조회속도가 너무 느릴때

2) 조회결과가 전체 데이타수의 3~5% 미만일 경우에 인덱스스캔이 효율적이고

적은비용으로 빠르게 데이터를 찾아낼수있습니다.

하지만 Acess 대상범위가 전체범위의 3~5%이상쯤 되면 인덱스스캔 보다 풀스캔이 휠씬

유리합니다.

 

인덱스 스캔 = Index Scan

풀 스캔 = Full Scan

 

INDEX가 불필요한 경우?

 

1) 데이터가 적은(수천건 미만) 경우에는 인덱스를 설정하지 않는게 오히려 성능이 좋습니다.

2) 조회 보다 삽입, 수정, 삭제 처리가 많은 테이블

3) 조회결과가 전체행의 15% 이상 읽어들일것으로 예상될때

 

Index 튜닝의 시기단계

 

하드웨어

DBMS 환경체크 - INDEX설정 및 파티셔닝체크 - SQL최적화  등의 레벨 순서로 튜닝합니다.

 

소프트웨어

쿼리문의 조회조건이 인덱스를 타는지 체크한다.(조금 중요)

 

쿼리문의 JOIN키가 모두 INDEX 설정이 되어 있는지 체크한다. INDEX설정이 되어 있지 않는 컬럼을 JOIN키로 지정했다면 조회속도가 많이 느려질수 있다.(많이 중요)

 

INDEX 생성하는 방법?

 

자동 생성

 

유일 인덱스는 테이블 정의시 PRIMARY KEY와 UNIQUE KEY 제약조건을 정의할때 자동으로 생성한다.

 

수동 생성

 

사용자는 행에 대한 액세스 시간을 향상 시키기 위해 열에서 유일하지 않은 인덱스를 생성할수 있다.

 

INDEX 생성 문법?

 

사용형식

 

CREATE INDEX index_name ON table_name (column_name)

--단일 인덱스 지정

CREATE INDEX index_name ON table_name (column_name1,column_name2,column_name3)

--다중 인덱스(복합 인덱스) 지정

 

※ 복합 인덱스로 지정해준 테이블에서 복합 인덱스를 타게 하려면 복합 인덱스로 준 컬럼

을 조회쿼리에서 모두 조회조건에 사용해야 인덱스를 탈 확률이 높아진다.

 

사용예제

 

create index index_a_date on account(a_date);

create index index_a_date on account(a_date, b_date, c_date);

 

※ null 허용 컬럼은 인덱스를 만들수 없습니다.

 

INDEX 가능 컬럼

 

인덱스는 모든 컬럼에 적용가능하다.

그런데 오라클은 가공시킨 컬럼에도 적용가능하다. 아래 참고

 

CREATE INDEX IDX_NAME ON TABLE_NAME(ROUND(PRICE1-PRICE2));

 

ROUND(PRICE1-PRICE2) 는 컬럼은 아니지만 컬럼을 가공해서 만든것이다.

이런 가공컬럼은 다음과 같은 SQL 쿼리로 인덱스를 탈수 있다.

 

SELECT * FROM TABLE_NAME WHERE ROUND(PRICE1-PRICE2) > 0

 

※ 인덱스 줄때의 가공컬럼과 같아야 합니다.

 

SQL 쿼리의 INDEX SCAN 유무 체크 방법

 

1. 상용 DB 관리도구를 이용하는 방법

 

PL/SQL Developer, Toad 같은 도구에서 SQL문을 작성하고 실행하면 Explain plan 에서 확인 가능합니다.

 

INDEX를 사용해야할 컬럼은?

 

where절이나 조인 조건에서 자주 사용되는 열에 생성

열은 광범위한 값을 포함할때

열은 많은수의 null값을 포함할때

조회결과가 전체행의 2-4% 보다 적게 읽어들일것으로 예상될때

--테이블이 클때 적은 양의 로우를 검색할때 인덱스를 줍니다. 적은 양을 검색하는데 테이블을 전체 풀스캔하면 시간이 오래 걸려서 꼭 index를 줘야 합니다.

 

INDEX를 사용하지 말아야할 컬럼은?

 

테이블에 데이타가  작은 경우

where절에 자주 사용되지 않는 열은 사용되지 않는다.

조회결과가 전체행의 2-4% 이상을 읽어들일것으로 예상될때

테이블이 자주 갱신된다.

 

INDEX 생성시 고려사항?

 

고려사항

 

인덱스가 적용된 컬럼이 조건식에서 인덱스를 탈수있게  하려면 해당컬럼을 가공하지않거나 연산을 하지 않은 상태에서 비교해야 인덱스를 탑니다.

예를들어 연락처컬럼의경우(016-293-1965) 016 만 따로 문자열을 잘라(가공) 조건검색하면 인덱스를 타지 않습니다.

왜냐하면 인덱스 컬럼에 변형이 일어나면 상대값과 비교되기 전에 먼저 가공이 된 후에 비교된다.하지만 인덱스는 가공되기 전의 값으로 생성되어 있기 때문에 당연히 인덱스를 사용할 수 없게 된다. 여기에서 외부적(External) 변형이란 사용자가 인덱스를 가진 컬럼을 어떤 SQL함수나 사용자 지정함수(User Defined Stored Function), 연산, 결합(||) 등으로 가공을 시킨 후에 발생되는 것이며 이러한 경우는 인덱스를 탈수 없어 변형이 일어나지 않도록 제대로 기술해야 합니다.

그렇기때문에 016과 293과 1965를 각각의 컬럼으로 만들어 저장한후 각각의 컬럼에 인덱스를 주면

아무런  가공없이 조건 검색이 가능하므로 인덱스를 탈수 있습니다.

 

테이블 컬럼에 인덱스가 있따면 테이블 컬럼을 변경하는것보다 비교값을 변경하여

비교해주는데 좋다. 왜냐면 그래야 인덱스를 타기 때문이다.

WHERE to_char(joindate, 'yyyymmdd') = '20070612'

WHERE joindate = TO_DATE('20070612','yyyymmdd')

 

아래는 인덱스를 타지 않습니다.

 

SELECT * FROM ACCOUNT WHERE A_DAY+1>2;

SELECT * FROM ACCOUNT WHERE SUBSTR(A_STRDAY,1,1)='월';

SELECT * FROM EMP WHERE  EMP_ID = NVL(EMP_ID,'10');

 

아래는 인덱스를 탑니다.

 

SELECT * FROM ACCOUNT WHERE A_STRDAY='월요일';

SELECT * FROM ACCOUNT WHERE A_DAY>2;

SELECT * FROM    EMP WHERE  EMP_ID = NVL('10','20');

SELECT * FROM ACCOUNT WHERE A_STRDAY like '월요일%';

 

※ 첫번째 쿼리부터 인덱스효과가 크게 나타나는 순입니다.

 

INDEX 타는 경우와 안타는 경우

 

안타는 경우

1. SELECT * FROM emp WHERE empno <> '7369';

 

※ 오라클에서는 인덱스 타게 가능(exists 이용)

SELECT * FROM emp WHERE not exists

(select empno FROM emp WHERE empno = '7369' and a.empno = b.empno);

 

INDEX 보기?

 

SELECT * FROM USER_INDEXES

--데이터 사전 뷰는 인덱스의 이름과 그것의 유일성을 디스플레이 합니다.

 

SELECT * FROM USER_IND_COLUMNS

--뷰는 인덱스명,테이블명,열명을 디스플레이 합니다.

 

SELECT * FROM ALL_OBJECTS where object_type='INDEX';

--현재 계정에 생성된 모든 인덱스 보기(속도느림)

 

SELECT * FROM USER_OBJECTS WHERE OBJECT_TYPE='INDEX';
--현재 계정에 생성된 모든 인덱스 보기(속도빠름)

 

select ic.index_name,
       ic.column_name,
       ix.uniqueness
from   user_indexes ix, user_ind_columns ic
where  ic.index_name = ix.index_name
and    ic.table_name = 'ACCOUNT';
--ACCOUNT TABLE의 인덱스 정보를 검색합니다.

 

INDEX 삭제?

사용형식

DROP INDEX INDEX_NAME;

사용예제

DROP INDEX BYC_LOVE_IDX;

 

※ TABLE이 삭제되면 INDEX도 삭제된다.

※ 인덱스의 소유자와 DROP ANY INDEX권한을 가진 사람만 인덱스 삭제가 가능합니다.

 

datecolumn => '20060517' and datecolumn <= '20060517' 좌측의 쿼리가 인덱스 안

타는 경우

1. 인덱스키가 아님

2. 복합키 인덱스인데 첫번째 컬럼에 조건을 안준 경우

3. 인덱스 스캔을 했을때 전체 데이터의 10~15% 이상이 되어 옵티마이져가 판단했을때

4. 인덱스 스캔이 불리하다고 판단되어 강제로 인덱스안타는 풀스캔 타는 경우

5. 좌변이 가공되어 인덱스 안탐

 

자주 쓰이지 않는 통계용 쿼리에는 인덱스를 주지 않는다.

여기서 인덱스를 준다는 얘기는 조건절에 인덱스를 안타는 컬럼에 인덱스를 생성해준다는

얘기이다. 이때는 create temp table as 해서 임시 테이블 만들어 통계 내용을 모두 담은후에

해당 조건컬럼에 인덱스를 만들어 쿼리하는게 좋다.

:
Posted by 라면스프
2011. 10. 10. 13:21

[ORACLE] 경과된 시간 날짜 계산 Enjoy/ORACLE2011. 10. 10. 13:21

날짜와 날짜 사이 경과 시 분 초 구하는 예제.

select TRUNC((to_date('20111010100203','yyyymmddhh24miss')-to_date('20111009090000', 'yyyymmddhh24miss'))*24) || ' hour ' || 

       TRUNC(mod((to_date('20111010100203','yyyymmddhh24miss') - to_date('20111009090000', 'yyyymmddhh24miss'))*24,1)*60) || ' minute ' ||

       TRUNC(round(mod((to_date('20111010100203','yyyymmddhh24miss') - to_date('20111009090000', 'yyyymmddhh24miss'))*24*60,1)*60)) || ' second '

from dual
;

아래는 참고한 사이트


출처 : http://cafe.naver.com/coolkkm1/19



- 시간구하기

select (to_date('1800', 'hh24mi') - to_date('0900', 'hh24mi'))*(24*60*60 )
 from dual;

to_date 로 계산후

(24 -- 시간표시

*60 -- 분표시

*60 ) -- 초표시

 

- 현재시간에 시간 추가하기

select sysdate,sysdate+1/(24*60)*10 from dual

 

sysdate+1은 1일 이후입니다.

그래서 1/(24*60)은 1분입니다.

10을 마지막에 곱하면 10분이죠 ^^

일 가(감) 산 SYSDATE + 1

시간 가(감) 산 SYSDATE + 1/24

분 가(감) 산 SYSDATE + 1/24/60

초 가(감) 산 SYSDATE + 1/24/60/60

 

-- 날자와 날짜사이의 시간 구하기
select to_date('2005050309','yyyymmddhh')-to_date('2005050409', 'yyyymmddhh'))*24
from dual;
;
                               
-- 날짜에 시간더하기
select to_char(to_date('200305021120', 'yyyymmddhh24mi'),  'yyyymmddhh24mi'),
to_char(to_date('200305021120', 'yyyymmddhh24mi') + (115/1440), 'yyyymmddhhmi') from dual;

 

-- 날짜수 구하기
select
  to_date('20050301', 'yyyymmdd')+1 - to_date('20050225', 'yyyymmdd')
from dual;
->여기서 하루치를 더한거는 그마지막 날을 포함하기 위해 하루를 더해야한다

 

-- 개월수 구하기
select months_between(to_date('20050131', 'yyyymmdd'), to_date('20010201', 'yyyymmdd')) from dual;

 

-- 그달의 마지막 날짜 구하기
select to_char(last_day(to_date('20040201','yyyymmdd')), 'yyyymmdd')
from dual;

select to_char(last_day(to_date('20040201','yyyymmdd')), 'mm')
from dual;

select to_char(last_day(to_date('20040201','yyyymmdd')), 'dd')
from dual;

 

-- 하루를 더추가하고 2달 뒤의 일자구하기
select to_char(add_months(to_date('20050201','yyyymmdd')+1, 2), 'yyyymmdd')
from dual;

 

-- 하루를 더추가하고 2달 앞의 일자구하기
select to_char(add_months(to_date('20050201','yyyymmdd')+1, 2), 'yyyymmdd')
from dual;


-- 해달일부터 2달 뒤의 일자구하기
select to_char(add_months(to_date('20050201','yyyymmdd'),2), 'yyyymmdd')
from dual;

 

- months_between : 두날짜간의 달수 구하기

select  months_between (to_date('20050201','yyyymmdd'), to_date('20050101', 'yyyymmdd'))
from dual;

 

- next_day 특정날자에서 가장가까운 요일의 날자 찾기

select next_day(to_date('20050101','yyyymmdd'), '일') from dual

 

TRUNC 함수의 제2 인수에'day'를 이용하면…….

SQL> select TRUNC(SYSDATE,'day') from dual;

TRUNC(SY
--------
05-02-13
리스트 4 이번 주의 주처음의 날을 취득

 

이러한 방법으로 간단하게 주의 처음의 날을 취득할 수 있습니다. 물론 SYSDATE 함수 대신에, SYSTIMESTAMP 함수를 사용할 수도 있습니다.다만, DATE형으로 변환되는 것은 기억해 둘 필요가 있습니다.

날짜 데이터로 TRUNC 함수를 사용하는 경우, 제2 인수에는'day'외에도 몇개인가 지정할 수 있습니다.메뉴얼을 확인하삼!!

 

TRUNC 함수를 사용한 샘플 SQL를  1개들어 둡니다.제목은 「이번 달의 제n○요일을 취득한다」

select decode(TRUNC(get_date,'mm'),TRUNC(SYSDATE,'mm'),get_date,null)
from (
select decode(TRUNC(TRUNC(TRUNC(SYSDATE,'mm'),'day') + :youbi -1,'mm')
             ,TRUNC(SYSDATE,'mm')
             ,TRUNC(TRUNC(SYSDATE,'mm'),'day') + :youbi -1
             ,TRUNC(TRUNC(SYSDATE,'mm'),'day') + :youbi -1 + 7)
      + (:nambanme - 1) * 7 get_date
from dual)
리스트 5 이번 달의 제n○요일을 취득한다

 

- sysdate = 19950725

-  round(sysdate, 'month') -> 19950801

-  round(sysdate,'year') -> 19960101

-  trunc(sysdate, 'month') -> 1950701

-  trunc(sysdate, 'year') -> 19950101

 

- 형식

 scc , cc : 세기 표현

 year : 년도를 영어로 표현

yyyy, yyy, yy, y : 년도를 자릿수로 자른다

bc, ad : 서기 등으로 표시

q : 분기 표시

mm : 두자리로 월표시

month: 영어로 표시

mon: 영어로 3자리로 월표시

rm: 로마자로 표시 i, ii. xi

ww: 1년기준 몇째주 표시

w:한달기준 몇째주 표시

ddd: 365(1년기준 ) 의 몇째 일

dd: 날짜를 두자리로 표시

d: 요일을 숫자로 표시

dy : 요일 한자리로 표시

day: 요일 표시

am, pm, a.m. , p.m. : 오전오후 표시

hh, hh12 : 12시 기준으로 표시

hh24 : 24시 기준으로 표시

/, "of" : 날짜의 중간에 문자 표시 -> to_char(to_date('19951201', 'yyyymmdd'),'yyyy "of" mm/dd')

spth : 날짜를 영문 서수로 표시

sp : 날짜를 영문 숫자로 표시

 





출처 : http://blog.naver.com/uhjinmo/80021617480


-- 두 날짜(date type)사이의 시분초 계산하기

-- 한 레코드에 속하지 않은 각각의 Attribute인 경우를 가정함

 

-- 간단히 시간계산은

 

-- 첫째 방법
select (A.endtime - B.starttime) * (24*60*60)
from (select endtime
        from iptimetable where marketclass = 1
        ) A
     , (select starttime
        from iptimetable where marketclass = 2
        ) B     ;

 

-- 두번째 방법
select to_char((A.endtime - B.starttime) * (24*60*60),'099999')
from (select endtime
        from iptimetable where marketclass = 1
        ) A
     , (select starttime
        from iptimetable where marketclass = 2
        ) B     ;

 

-- 시분초로 변환
select trunc(mod((A.endtime - B.starttime)*24,1)*60) || ' 분 ' ||
trunc(round(mod((A.endtime - B.starttime)*24*60,1)*60)) || ' 초 '
from (select endtime
        from iptimetable where marketclass = 1
        ) A
     , (select starttime
        from iptimetable where marketclass = 2
        ) B     ;

 

-- 일,시간,분,초로 표현
select trunc(A.endtime - B.starttime) || ' day ' ||
trunc(mod((A.endtime - B.starttime),1)*24) || ' hour ' ||
trunc(mod((A.endtime - B.starttime)*24,1)*60) || ' minute ' ||
trunc(round(mod((A.endtime - B.starttime)*24*60,1)*60)) || ' second '
from (select endtime
        from iptimetable where marketclass = 1
        ) A
     , (select starttime
        from iptimetable where marketclass = 2
        ) B     ;

 

-- 또 다른 표현

SELECT FLOOR((to_time - from_time)*24) hh, 
( (to_time - from_time)*24 - FLOOR((to_time - from_time)*24) )*60 mm 
FROM (SELECT to_date('17:00','hh24:mi') to_Time, to_date('8:30','hh24:mi') from_Time FROM dual)

 

:
Posted by 라면스프



제목

Oracle의 connect by 를 Mssql2005 의 CTE(WITH common_table_expression)로 변환

작성자

DEV.NAM( http://blog.naver.com/kilnam50)

작성일

2007-10-29

배포

public (단, 출처는 꼬~~~옥 밝혀 주세요)

출처

MSDN

 

 

 

 

SELECT GROUP_CODE, TASK_CODE, UPPER_TASK_CODE, TASK_NAME, ORDER_DESC, LEVEL AS LEV
  FROM BPM_TEMPLETE
 WHERE GROUP_CODE=2
CONNECT BY PRIOR TASK_CODE = UPPER_TASK_CODE
START WITH UPPER_TASK_CODE = 0
order by order_desc

 

 

위와 같은 방식으로 출력하기 위해서는 CTE와 집계함수를 이용하면 된다.

 

처음 CTE의 구조를 몰랐을 때는 왜 이렇게 나오는 몰라서 참 고민을 많이 했었다.

 

하지만 구조를 이해하고 나면 정말 간편하게 출력할 수 있게 되었다.

 

 

처음으로 CTE의 기본 문법만 사용하면 아래와 같이 쿼리를 작성할 수 있다.

 

WITH BPM_CTE(GROUP_CODE, TASK_CODE, UPPER_TASK_CODE, TASK_ORDER, TASK_NAME, TASK_DESC, TASK_ROLL, ORDER_DESC, LEVEL)
AS
(
    SELECT GROUP_CODE, TASK_CODE, UPPER_TASK_CODE, TASK_ORDER, TASK_NAME, TASK_DESC, TASK_ROLL, ORDER_DESC, 1 AS LEVEL
 FROM BPM_TEMPLETE T
 WHERE GROUP_CODE=2

    UNION ALL
   SELECT C.GROUP_CODE, C.TASK_CODE, C.UPPER_TASK_CODE, C.TASK_ORDER, C.TASK_NAME, C.TASK_DESC, C.TASK_ROLL, C.ORDER_DESC, LEVEL+1
  FROM BPM_TEMPLETE C
 INNER JOIN BPM_CTE P
 ON C.UPPER_TASK_CODE = P.TASK_CODE
 WHERE C.GROUP_CODE=2
)
SELECT GROUP_CODE, TASK_CODE, UPPER_TASK_CODE, TASK_ORDER, TASK_NAME, TASK_DESC, TASK_ROLL, ORDER_DESC, LEVEL
FROM BPM_CTE
WHERE GROUP_CODE=2

ORDER BY ORDER_DESC ASC

 

 

 

 

결과는 위와같이 같은 정보에 LEVEL이 중복되어서 출력된다.

 

이와같이 나온 이유는 UNION ALL 이 일반적으로 적용되는 방식과 달라서 헷갈릴 것이다.

 

이유는

 

부모 ROW에 자식 ROW가 LEVEL이 증가하면서 쌓이기 때문에 위와같은 결과가 나올 수 밖에 없다.

 

그래서 집계함수를 사용하여 아래와 같이 쿼리를 작성하였다.

 

 

WITH BPM_CTE(GROUP_CODE, TASK_CODE, UPPER_TASK_CODE, TASK_NAME, ORDER_DESC, LEVEL)
AS
(
    SELECT GROUP_CODE, TASK_CODE, UPPER_TASK_CODE, TASK_NAME, ORDER_DESC, 1 AS LEVEL
 FROM BPM_TEMPLETE T
 WHERE GROUP_CODE=2

    UNION ALL
   SELECT C.GROUP_CODE, C.TASK_CODE, C.UPPER_TASK_CODE, C.TASK_NAME, C.ORDER_DESC, LEVEL+1
  FROM BPM_TEMPLETE C
 INNER JOIN BPM_CTE P
 ON C.UPPER_TASK_CODE = P.TASK_CODE
 WHERE C.GROUP_CODE=2
)
SELECT GROUP_CODE, TASK_CODE, UPPER_TASK_CODE, TASK_NAME, ORDER_DESC, MAX(LEVEL) AS LEVEL
FROM BPM_CTE
WHERE GROUP_CODE=2
GROUP BY GROUP_CODE, TASK_CODE, UPPER_TASK_CODE, TASK_NAME, ORDER_DESC

ORDER BY ORDER_DESC ASC

 

 

결과는 아래와 같이 깔끔하게 출력된다.

 

 

 

 

계층도를 뽑을 때 상당히 유용하게 사용되니 필요하신 분은 퍼가시고 Comment도 남겨주세요


:
Posted by 라면스프
출처 : http://www.oracleclub.com/lecture/1142
         oracleclub.com


LIKE연산으로 ’%’나 ’_’가 들어간 문자를 검색하기 위해서는 ESCAPE를 사용해야 합니다.
’_’나 ’%’앞에
ESCAPE로 특수 문자를 지정하면 검색할 수 있습니다.


1. ’_’ 가 있는 문자 검색

 SQL>SELECT   loc
         FROM   dept
         WHERE   loc like ’%#_%’ ESCAPE ’#’;
        
LOC
-------------
NEW_YORK      
  
 
위 문장에서 #대신 다른 문자가 와도 됩니다.
(아래같이 @같은 특수 문자나, A같은 아파벳이나, 9같은 숫자가 와도 똑같은 결과가 나오네요)

아래의 결과들을 한번 비교해 보시기 바랍니다.

SQL> SELECT   loc
         FROM   dept
         WHERE   loc like ’%N%@_%ESCAPE ’@’
        
LOC
-------------
NEW_YORK   
     
 

 
SQL>SELECT loc
        FROM dept
        WHERE loc like ’%_%’;
        
LOC
-----------
NEW_YORK
DALLAS
CHICAGO
BOSTON




2, ’%’ 가 있는 문자 검색

’%’가 있는 문자도 ’_’가 있는 문자 검색과 동일 합니다.

SQL>SELECT loc
        FROM dept
        WHERE loc like ’%@%%’ ESCAPE ’@’;
 
LOC
-------------
BOS%TON

 
 
SQL>SELECT loc
       FROM dept
       WHERE loc like ’%%%’;

LOC
-------------
NEW_YORK
DALLAS
CHICAGO
BOS%TON





  ================================================
    * 데이터베이스 정보공유 커뮤니티 oracleclub.com
    * 강좌 작성자 : 김정식 (oramaster _at_ naver.com)
  ================================================
※ oracleclub 강좌를 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
※ oracleclub 강좌는 개인의 학습용으로만 사용 할 수 있습니다. 학원 홍보용이나 수익을 얻기 위한 용도로
    사용을 하시면 안됩니다. ^^

:
Posted by 라면스프