회사에서 오라클을 이용하여 오라클 관련 책을 사게되었다 
오라클 성능 고도화 원리와 해벅1
오라클 성능 고도화 원리와 해법2
이 두권 ... 기격은 거이 8마넌가까이한다.. 컴퓨터 책은 너무 비싼듯하다.
책내용은 대학교때 공부하던 수준의....딱딱한 내용의 책이다.. 내가 싫어하는 스타일 ㅠㅠ
공부하면서 정리를 해볼려고한다.
책 1은 너무 기초와 원리가있어서 보기가 졸립다 나중에 함 다시 보기로하고 2권 으로 넘어가자 ㅎㅎ

1. 쿼리중 where  잘못쓰는 예

SELECT * FROM table where   
 잘못된경우  쿼리 수정
 substr(필드,1,2)='조건'  필드1 like '조건%'
 where 필드1<>'조건'  '조건' and 필드 <'조건'    // 경우에 따라 다름
 where 필드*12 = 350  필드 = 3500*12
   
   
   

필드가공, 부정형 , null 체크 등을 할경우 table full scan 현상이 발생한다.


2. 형변환 오류

varchar2 형을  + 거나 - 면서 데이터를 비교할때 문제가 생길수있다.

필드1 = substr('20091020',1,6)-1

이런 조건 절이라면

필드1 = TO_char(add_months(to_date('20091020','yyyymmdd'),-1),'yyyymm')

요런식으로 변경해보자 ...


3.형변환 필요성

--> 만약 다른형식의 데이터를 비교할때는 꼭 형변환을 한다. 

      이유는 DBMS가 형변환할때 여러가지이유로 정확한 데이터를 제공할수 없을수 있기 때문이다

      특히 Decode 함수를 이용할때 주의해야한다.

      문자 날짜일경우는 날짜로 

      문자 숫자일경우는 숫자로

      형변환 해준다.

Decode 설명있는곳  영문이라 어려움 이해는 안간다 ㅡㅡ;;

http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/functions040.htm

문자 조작 함수
CONCAT(column1 | expression1, column2 | expression2)

문자붙이기

SELECT concat(job,sal)
FROM emp;

CLERK800
SALESMAN1600
SALESMAN1250

SUBSTR(column | expression, m[,n])
위치 m에서 n개 지정된 문자를 반환
m이 음수면 문자 값의 끝부터 세며, n을 생략하면 끝까지 반환 n=갯수
SELECT SUBSTR(job, 1,6)
FROM emp;

SUBSTR(JOB,1 ,6)
CLERK
SALESM
SALESM
MANAGE

LENGTH(column | expressio)
문자수 반환 ,문자열의 길이
SELECT ename, length(ename)
FROM emp;

 

INSTR(column | expression, 'string', [,m],[n])
지정된 문자열의 위치를 숫자로 반환
SELECT INSTR('Hello,World', ',W')
FROM dual;

---->6

LPAD(column | expression, n, 'string') **800
전체 폭이 n이 되도록 문자 값을 오른쪽으로 정렬하고 빈 곳을 지정한 string으로 채운다.

RPAD(column | expression, n, 'string)800**
전체 폭이 n이 되도록 문자 값을 왼쪽으로 정렬하고 빈 곳을 지정한 string으로 채운다.

SELECT LPAD(sal, 5, '*'), RPAD(sal, 6, '*')
FROM emp;

 

SELECT ename, CONCAT(ename, job),
LENGTH(ename), INSTR(ename, 'A'),
LPAD(sal, 5, '*'), RPAD(sal, 6, '*')
FROM emp
WHERE SUBSTR(job, 1, 5) = UPPER('sales');

ENAME CONCAT(ENAME,JOB) LENGTH(ENAME) INSTR(ENAME,'A') LPAD(SAL,5 RPAD(SAL,6,'
ALLEN ALLENSALESMAN 5 1 *1600 1600**
WARD WARDSALESMAN 4 2 *1250 1250**
MARTIN MARTINSALESMAN 6 2 *1250 1250**
TURNER TURNERSALESMAN 6 0 *1500 1500**

CHR
숫자에 맞는 ASCII문자 출력
SELECT CHR(65)
FROM dual;

 

ASCII
해당 ASCII로 변환
SELECT ASCII('a')
FROM dual;

 

LTRIM
정의된 문장에서 왼쪽에서 지정된 단어가 나타나면 제거
SELECT LTRIM('xyxXxyLAST WORD', 'xy')
FROM dual;

---->XxyLAST WORD

RTRIM
정의된 문장에서 오른쪽에서 지정된 단어가 나타나면 제거
SELECT RTRIM('TURNERyxXxy', 'xy')
FROM dual;

 

REPLACE
해당문자가 발견되면 지정된 문자로 변환
SELECT REPLACE('JACK and JUE', 'J', 'BL')
FROM dual;

REPLACE('JACKA
BLACK and BLUE

GREATEST
주어진 단어 중 가장 높은 값
SELECT GREATEST('HARRY', 'HARIOT', 'HALORD')
FROM dual;
처음에는 H부터 비교 -> A비교 ->

LEAST
주어진 단어 중 가장 낮은 값
SELECT LEAST('HARRY', 'HARIOT', 'HALORD')
FROM dual;

 

NVL
칼럼이 NULL이면 지정한 값으로 대치
SELECT NVL(sal, 0), NVL(ename, '*'),
NVL(hiredate, SYSDATE)
FROM emp;

검색 명령에
select * from all_db_links;
입력하면 해당 DB에 연결되어있는 DB 링크 리스트가 보인다.

select /* 오늘날짜 시분초 포함*/
              to_char(sysdate,'yyyy/mm/dd hh24:mi:ss')
    from dual

 
select /* 오늘날짜 00시 00분 00초 */
              to_char(trunc(sysdate),'yyyy/mm/dd hh24:mi:ss')
    from dual
 
select /* 오늘날짜 00시 00분 00초 위와 동일*/
              to_char(trunc(sysdate,'dd'),'yyyy/mm/dd hh24:mi:ss')
    from dual

select /* 이번달 1일 00시 00분 00초 */
              to_char(trunc(sysdate,'mon'),'yyyy/mm/dd hh24:mi:ss')
    from dual

select /* 올해 1월 1일 00시 00분 00초 */
              to_char(trunc(sysdate,'year'),'yyyy/mm/dd hh24:mi:ss')
    from dual
 
select /* 올해 1월 1일 00시 00분 00초 */
              to_char(to_date('2002','yyyy'),'yyyy/mm/dd hh24:mi:ss')
    from dual
 
select /* 2월 1일 00시 00분 00초 */
              to_char(to_date('200202','yyyymm'),'yyyy/mm/dd hh24:mi:ss')
    from dual

select /* 2월 2일 00시 00분 00초 */
              to_char(to_date('20020202','yyyymmdd'),'yyyy/mm/dd hh24:mi:ss')
    from dual
 
select /* 2월 2일 00시 00분 01초 */
              to_char(to_date('20020202','yyyymmdd')+1/68400,'yyyy/mm/dd hh24:mi:ss')
    from dual
 
select /* 2월 2일 00시 00분 00초 -> 한달뒤*/
              to_char(add_months(to_date('20020202','yyyymmdd'),1),'yyyy/mm/dd hh24:mi:ss')

 from dual
 
from en-core
laalaal~
 
 
날짜 빼기
 
밑에 날짜 빼기가 있던데 요건 약간 다르게..
(1) 현재 날자에서 하루를 빼고 싶다고 하면
            select sysdate() - 1 from dual
(2) 1시간을 빼고 싶으면
            select sysdate() - 1/24 from dual
(3) 1분을 빼고 싶으면
            select sysdate() - 1/24/60
(q) 1초를 빼고 싶은면 어떻게 할까요? ^^
 
======================================================================================
- 날짜형 함수

    SYSDATE : 현재 시스템의 날짜 및 시간을 구함

    LAST_DAY : 지정한 날짜의 해당 월의 마지막 날짜를 구함

    MONTHS_BETWEEN : 두 날짜 사이의 개월 수를 구함

    ADD_MONTHS : 지정한 날짜로부터 몇 개월 후의 날짜를 구함

    ROUND : 날짜에 대한 반올림

    TRUNC : 날짜에 대한 버림

 

    SYSDATE : SYSDATE 10-MAY-99

    LAST_DAY(날짜값) : LAST_DAY('17-FEB-98') 28-FEB-98

   MONTHS_BETWEEN(날짜값1, 날짜값2) : MONTHS_BETWEEN('26-APR-97','22-JUL-95') 21.1290323

   ADD_MONTHS(날짜값, 숫자값) : ADD_MONTHS('22-JUL-95',21) 22-APR-97

      ROUND(날짜값, 자리수) : 현재 날짜가 1999년 5월 10일이라고 가정하자.

                              ROUND(SYSDATE,'MONTH') 01-MAY-99

      TRUNC(날짜값, 자리수) : 현재 날짜가 1999년 5월 10일이라고 가정하자.

                              TRUNC(SYSDATE,'YEAR') 01-JAN-99

 

  - 날짜에 대한 산술연산

    날짜 + 숫자 : 날짜 특정한 날로부터 몇일 후의 날짜 계산

    날짜 - 숫자 : 날짜 특정한 날로부터 몇일 전의 날짜 계산

    날짜 - 날짜 : 숫자 두 날짜 사이의 차이를 숫자로 계산

 

- 변환형 함수

    TO_CHAR : 숫자나 날짜를 문자열로 변환

    TO_NUMBER : 문자를 숫자로 변환

    TO_DATE : 문자를 날짜로 변환

 

      - TO_CHAR에서 숫자를 문자로 변환시에 형식에 사용되는 요소

          9 : 일반적인 숫자를 나타냄

          0 : 앞의 빈자리를 0으로 채움

          $ : dollar를 표시함

          L : 지역 통화 단위(ex \)

          . : 소숫점을 표시함

          , : 천단위를 표시함

      - TO_CHAR에서 날짜를 문자로 변환시에 형식에 사용되는 요소

          SCC : 세기를 표시 S는 기원전(BC) 

          YEAR : 연도를 알파벳으로 spelling

          YYYY : 4자리 연도로 표시

          YY : 끝의 2자리 연도로 표시

          MONTH : 월을 알파벳으로 spelling

          MON : 월의 알파벳 약어

          MM : 월을 2자리 숫자로 표시

          DAY : 일에 해당하는 요일

          DY :  일에 해당하는 요일의 약어

          DDD,DD,D : 연도,월,일 중의 날짜를 숫자로 표시

          HH , HH24 : (1-12) , (0-23)중의 시간을 표시

          MI : 분을 표시

          SS : 초를 표시

          AM(A.M.),PM(P.M.) : 오전인지 오후인지를 표시

 

      TO_CHAR(문자값,형식)

        숫자를 문자로 변환 : TO_CHAR(350000,'$999,999') $350,000

        숫자를 날짜로 변환 : TO_CHAR(SYSDATE,'YY/MM/DD') 95/05/25

      TO_DATE(문자값, 형식) : TO_DATE('10 SEPTEMBER 1992','DD MONTH YYYY')10-SEP-92

      TO_NUMBER(문자값) : TO_NUMBER('1234') 1234





오라클 날짜함수

출처:http://blog.naver.com/pumba3/10006685033

# 날짜계산
select months_between(sysdate,to_date('2002-12-22','yyyy-mm-
dd'))
-- months_between(A,B) = A-B/30
--select add_months(sysdate,4) -- 특정일의 달수 더한 날
--select next_day(sysdate,'friday') -- 특정일의 다음주 요일
--select last_day(sysdate) -- 특정일의 해당 월의 마지막 날
--select round(sysdate,'dd') -- 특정일의 반올림(오후면 다음날..)
--select trunc(sysdate,'ww') -- 특정일의 전주 토요일(해당 전주의 마지막 날)에해당하는 날짜
--select trunc(sysdate,'D') -- 특정일의 주 일요일(해당 주의 첫째 날)에해당하는 날짜

from dual
 

/* 어제 */ 날짜칼럼 BETWEEN TRUNC(SYSDATE-1) AND TRUNC(SYSDATE-1)+0.99999421
/* 오늘 */ 날짜칼럼 BETWEEN TRUNC(SYSDATE) AND TRUNC(SYSDATE) + 0.99999421
/* 내일 */ 날짜칼럼 BETWEEN TRUNC(SYSDATE+1) AND TRUNC(SYSDATE+1)+0.99999421
/* 금주 */ 날짜칼럼 BETWEEN TRUNC(SYSDATE+1)-TO_CHAR(SYSDATE,'D')
                        AND TRUNC(SYSDATE+1)-TO_CHAR(SYSDATE,'D')+6.99999421
/* 차주 */ 날짜칼럼 BETWEEN TRUNC(SYSDATE+8)-TO_CHAR(SYSDATE, 'D')
                        AND TRUNC(TRUNC(SYSDATE)+14.99999421)-TO_CHAR(SYSDATE, 'D')
/* 금월 */ 날짜칼럼 BETWEEN TRUNC(SYSDATE+1)-TO_CHAR(SYSDATE,'DD')
                        AND TRUNC(LAST_DAY(SYSDATE))+0.99999421
/* 전월 */ 날짜칼럼 BETWEEN TRUNC(ADD_MONTHS(SYSDATE,-1)+1)-TO_CHAR(SYSDATE,'DD')
                        AND TRUNC(LAST_DAY(ADD_MONTHS(SYSDATE, -1)))+0.99999421
/* 차월 */ 날짜칼럼 BETWEEN ADD_MONTHS(TRUNC(SYSDATE),1)-TO_CHAR(SYSDATE,'DD')+1
                        AND LAST_DAY(ADD_MONTHS(TRUNC(SYSDATE),1)+0.99999421)

 

 

# 특정일 까지의 간격을 년, 개월, 일로 표현하기

SELECT
TRUNC(MONTHS_BETWEEN(SYSDATE, TO_DATE('19970101', 'YYYYMMDD'))/12) "년",
TRUNC(MONTHS_BETWEEN(SYSDATE, TO_DATE('19970101', 'YYYYMMDD')) -
TRUNC(MONTHS_BETWEEN(SYSDATE, TO_DATE('19970101', 'YYYYMMDD'))/12) * 12) "개월",
TRUNC((MONTHS_BETWEEN(SYSDATE,TO_DATE('19970101', 'YYYYMMDD')) -
TRUNC(MONTHS_BETWEEN(SYSDATE, TO_DATE('19970101', 'YYYYMMDD')))) * 30.5) "일"
FROM DUAL;

 


# 당월의 주차 구하기..
SELECT
'20040511' as "날짜"
, ceil((to_number(substrb('20040511', -2, 2)) + 7 - to_number(TO_CHAR(TO_DATE('20040511','YYYYMMDD'),'D')))/7) as "월별 주차"
from dual;


 

# 시간 계산 SQL
SELECT TRUNC(TO_DATE('20010502223443','YYYYMMDDHH24MISS')-TO_DATE('20010501213344','YYYYMMDDHH24MISS')) || ' day ' ||
       TRUNC(MOD((TO_DATE('20010502223443','YYYYMMDDHH24MISS')-TO_DATE('20010501213344','YYYYMMDDHH24MISS')),1)*24) || ' hour ' ||
       TRUNC(MOD((TO_DATE('20010502223443','YYYYMMDDHH24MISS')-TO_DATE('20010501213344','YYYYMMDDHH24MISS'))*24,1)*60) || ' minute ' ||
       TRUNC(ROUND(MOD((TO_DATE('20010502223443','YYYYMMDDHH24MISS')-TO_DATE('20010501213344','YYYYMMDDHH24MISS'))*24*60,1)*60)) || ' sec '
       " Time Interval "
FROM DUAL ;