흐르는 시간의 블로그...


원본 출처 :https://sites.google.com/site/smcgbu/home/gongbu-iyagi/naljjahyeonghamsu



날짜형 함수

-SYSDATE : 시스템의 현재 날짜/시간
-CURRENT_DATE : 세션별 시간대(TIME_ZONE)를 기준으로 한 날짜/현재 시간. Oracle은 세션별로 시간대 설정 가능 (파라미터 : TIME_ZONE)
-SYSTIMESTAMP : 시스템의 현재 날짜/시간 (반환 타입이 DATE가 아닌 TIMESTAMP WITH TIME ZONE 타입을 반환)
-CURRENT_TIMESTAMP: 세션별 시간대(TIME_ZONE)를 기준으로 한 날짜/현재 시간 (반환 타입이 DATE가 아닌 TIMESTAMP WITH TIME ZONE 타입을 반환)
파라미터 있음(TIMESTAMP WITH TIME ZONE의 정밀도. 생략시는 default 6)
-LOCALTIMESTAMP : (반환 타입이 TIMESTAMP WITH TIME ZONE 아닌 TIMESTAMP 타입을 반환)
파라미터 있음(TIMESTAMP WITH TIME ZONE의 정밀도. 생략시는 default 6)
select sysdate --> 2011-10-17 10:52:36
, current_date --> 2011-10-17 10:52:36
, systimestamp --> 17-OCT-11 10.52.36.043602 AM +09:00
, current_timestamp --> 17-OCT-11 10.52.36.043602 AM +09:00
, current_timestamp(6) --> 17-OCT-11 10.52.36.043602 AM +09:00
, current_timestamp(5) --> 17-OCT-11 10.52.36.04360 AM +09:00
, current_timestamp(4) --> 17-OCT-11 10.52.36.0436 AM +09:00
, current_timestamp(3) --> 17-OCT-11 10.52.36.044 AM +09:00
, current_timestamp(2) --> 17-OCT-11 10.52.36.04 AM +09:00
, current_timestamp(1) --> 17-OCT-11 10.52.36.0 AM +09:00
, current_timestamp(0) --> 17-OCT-11 10.52.36 AM +09:00
, current_timestamp(-1) -->ORA-30088: datetime/interval precision is out of range
, localtimestamp --> 17-OCT-11 10.54.36.043602 AM
, localtimestamp(6) --> 17-OCT-11 10.54.36.043602 AM
, localtimestamp(5) --> 17-OCT-11 10.54.36.04360 AM
, localtimestamp(4) --> 17-OCT-11 10.54.36.0436 AM
, localtimestamp(3) --> 17-OCT-11 10.54.36.044 AM
, localtimestamp(2) --> 17-OCT-11 10.54.36.04 AM
, localtimestamp(1) --> 17-OCT-11 10.54.36.0 AM
, localtimestamp(0) --> 17-OCT-11 10.54.36 AM
, localtimestamp(-1) -->ORA-30088: datetime/interval precision is out of range
from dual;

--> sysdate 외에는 아직 써 본적이 없네요.

*** 실수로 데이터를 변경했을 때 좋은 것 같아요 ***

1. 특정시간의 데이터 조회
select * from 테이블명 as of timestamp to_date('2011101612','yyyymmddhh24') where rownum < 10;
2. 한시간 전 데이터 조회
select * from 테이블명 as of timestamp (systimestamp - interval '1' hour) where rownum < 10;
3. 1분전 데이터 조회
select * from 테이블명 as of timestamp (systimestamp - interval '1' minute) where rownum < 10;

-ADD_MONTHS(date, integer) : 임의의 날짜에 개월 수를 더함
select trunc(sysdate), add_months(trunc(sysdate), 2) from dual;
-----------------------------------------------------------------------
2011-10-17 00:00:00 2011-12-17 00:00:00

-MONTHS_BETWEEN(date1, date2) : 두 날짜 사이의 개월 수
select months_between(to_date('20111207', 'yyyymmdd'), to_date('20110607', 'yyyymmdd')) from dual;
---------------------------------------------------------------------------------------------------
6

-NEXT_DAY(date, char) : date이후의 날짜 중에서 주중에 char로 명시된 첫 번째 일자를 반환
char : MONDAY, MON(SUN, MON, TUE, WED, THUR, FRI, SAT), 2(1:일요일, 7:토요일)
select next_day(trunc(sysdate), 'TUESDAY'), next_day(trunc(sysdate), 'TUE'), next_day(trunc(sysdate), 3) from dual;
-------------------------------------------------------------------------------------------------------------------
2011-10-18 00:00:00 2011-10-18 00:00:00 2011-10-18 00:00:00

-ROUND(date, fmt) : 파라미터로 들어오는 date 날짜를 포맷모델인 fmt에 의해 명시된 단위로 반올림한 결과를 반환
select round(trunc(sysdate), 'cc' ) century --> 2001-01-01 00:00:00
, round(trunc(sysdate), 'yyyy' ) next_year1 --> 2012-01-01 00:00:00
, round(trunc(sysdate), 'year' ) next_year1 --> 2012-01-01 00:00:00
, round(trunc(sysdate), 'iyyy' ) iso_year --> 2012-01-02 00:00:00 .. iso 년도 기준
, round(trunc(sysdate), 'q' ) quarter --> 2011-10-01 00:00:00
, round(trunc(sysdate), 'month') mon --> 2011-11-01 00:00:00
, round(trunc(sysdate), 'dd' ) dd --> 2011-10-17 00:00:00
, round(trunc(sysdate), 'day' ) day --> 2011-10-16 00:00:00
from dual;

-----------------------------------------------------------------
포맷 모델 단위
-----------------------------------------------------------------
CC 4자리연도의 끝 두 자리를 기준으로 반올림된다.
SCC
-----------------------------------------------------------------
SYYYY 년(7월 1일부터 반올림된다)
YYYY
YEAR
SYEAR
YYYY
YYY
Y
-----------------------------------------------------------------
IYYY ISO 기준 년(year)
IYY
IY
I
-----------------------------------------------------------------
Q 분기(한 분기의 두 번째 달의 16일부터 반올림된다)
-----------------------------------------------------------------
MONTH 월(16일부터 반올림된다)
MON
MM
RM
-----------------------------------------------------------------
WW 연도의 첫 번째 날짜로 그 주의 같은 날
-----------------------------------------------------------------
IW ISO 연도의 첫 번째 날짜로그 주의 같은 날
-----------------------------------------------------------------
WW 월의 첫 번째 날짜로 그 주의 같은 날
-----------------------------------------------------------------
DDD, DD, J 일
-----------------------------------------------------------------
DAY, DY, D 한 주가 시작되는 날짜
-----------------------------------------------------------------
HH, HH12, HH24 시
-----------------------------------------------------------------
MI 분
-----------------------------------------------------------------


-TRUNC(date, fmt) : date 날짜를 포맷모델에 맞게 날짜를 잘라낸다.
round 함수는 포맷모델에 따라 일정한 날짜를 기준으로 해서 반올림이 수행되는데 반해
trunc 함수는 이에 상관없이 무조건 잘라낸다.
select trunc(sysdate ) today --> 2012-02-16 00:00:00
, trunc(sysdate, 'cc' ) century --> 2001-01-01 00:00:00
, trunc(sysdate, 'yyyy' ) year1 --> 2012-01-01 00:00:00
, trunc(sysdate, 'year' ) year2 --> 2012-01-01 00:00:00
, trunc(sysdate, 'iyyy' ) iso_year --> 2012-01-02 00:00:00 .. iso 년도 기준
, trunc(sysdate, 'q' ) quarter --> 2012-01-01 00:00:00
, trunc(sysdate, 'month') mon --> 2012-02-01 00:00:00
, trunc(sysdate, 'dd' ) dd --> 2012-02-16 00:00:00
, trunc(sysdate, 'day' ) day --> 2012-02-12 00:00:00
from dual;

--> round와 trunc 함수 모두 포맷 모델을 생략할 수 있는데 이러한 경우 파라미터 값에 가장 가까운 날짜로 반올림되거나 잘린다.

-EXTRACT([YEAR] [MONTH] [DAY] [HOUR] [MINUTE] [SECOND]) ... FROM datetime)
: 파라미터로 들어오는 날짜정보에서 특정한 날짜 유형, 즉 연도나 월, 시간, 분, 초 등을 추출하여 그 결과를 반환
select extract(year fromsysdate ) year --> 2011
, extract(month from sysdate ) month --> 10
, extract(day from sysdate ) day --> 17
, extract(hour fromsystimestamp) hour --> 4
, extract(minute from systimestamp) minute --> 34
, extract(second from systimestamp) second --> 21.423162

, extract(year fromsystimestamp) --> 2011
, extract(hour fromsysdate ) -->ORA-30076: invalid extract field for extract source
from dual;

--> M.Jay 의견 : 기존에는 이런 데이터를 구할 때 trunc를 하거나 substr등을 사용하고는 했는데 이 함수를 사용하면 좋겠네요.

- 기타 날짜형 함수
DBTIMEZONE: 데이터베이스의 시간대 반환
select DBTIMEZONE from dual;
----------------------------
-04:00
SESSIONTIMEZONE: 현재 접속되어 있는 세션의 시간대 반환
select SESSIONTIMEZONE from dual;
---------------------------------
+09:00

출처 :http://develop.sunshiny.co.kr/34

/* 해당 일자에 속한 한주 일자를 출력 : 월~일 */
SELECT TRUNC(SYSDATE, 'IW') + LEVEL -1
FROM DUAL
CONNECT BY LEVEL <= 7
;

/* 해당 년도의 월일을 모두 출력 */
SELECT TRUNC(SYSDATE, 'YEAR') + LEVEL -1
FROM DUAL
CONNECT BY LEVEL <= 365
;


/* 주민번호로 나이 출력 : 출생년도만 입력되어도 가능.*/
SELECT TO_NUMBER(TO_CHAR(SYSDATE, 'YYYY')) -
TO_NUMBER(DECODE(SUBSTR('790518', 1, 1), '0', '20', '19') ||
SUBSTR('790518', 1, 2)) + 1 AGE
FROM DUAL
;


-- Oracle --
-- 날자 변환 형식 : 2009-01-03 -- > 2009년 01월 03일

SELECTTO_CHAR(SYSDATE,'YYYY"년" MM"월" DD"일"')AS TODAYFROM DUAL;


-- 현재 날자 시간
SELECT TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS') FROM DUAL

-- 이틀 전
SELECT TO_CHAR(SYSDATE-2, 'YYYYMMDDHH24MISS') FROM DUAL

-- 3분 전
SELECT TO_CHAR(SYSDATE-(3/(24*60)), 'YYYYMMDDHH24MISS') FROM DUAL

-- 현재 시간에서 20분을 뺀 시간
SELECT TO_CHAR(sysdate - 1/24/60 * 20, 'yyyymmddhh24mi') FROM dual

--------------------------------------------------------------

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 : 지정한 날짜의 해당 월의 마지막 날짜를 구함

-- 현재의 월의 마지막날자를 반환
SELECT LAST_DAY(SYSDATE) "REMAIN DAYS" FROM DUAL;

-- 현재 월의 남은 일수를 반환
SELECT (LAST_DAY(SYSDATE) - SYSDATE) "REMAIN DAYS" FROM DUAL;



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


-- MONTHS_BETWEEN(DATA1, DATA2)
-- 날자와 날자 사이의 기간을 월 로 나타냄. data1이 data2보다 큰 값

SELECT MONTHS_BETWEEN(LAST_DAY('20091231'), SYSDATE) "남은달" FROM DUAL;
남은달
---------------
10.81507616...




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

ROUND : 날짜에 대한 반올림

TRUNC : 날짜에 대한 버림



SYSDATE : SYSDATE10-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


- 날짜에 대한 산술연산

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

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

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


- 변환형 함수




오늘은 MS-SQl을 쓰다가 필요한 쿼리를 찾던 중 TO_CHAR로 된 쿼리를 찾았는데 써보니 MS-SQL용 쿼리가 아니라 ORACLE용 쿼리여서 제대로 쓸수가 없었습니다.
그래서 찾던 중 ORACLE의 TO_CAHR 함수를 MS-SQL의 CONVERT 함수로 대체할 수 있다는 것을 찾아서 이렇게 정리해 봅니다.

혹시나 저처럼 필요하신 분은 아래를 참조하시면 되겠습니다!!

출처 :
ORACLE의 TO_CHAR 함수를 MSSQL의 CONVERT 함수로


※ ORACLE에서 날짜를 처리할때는
TO_CHAR(SYSDATE,'YYYY-MM-DD') -> 2003-01-23
TO_CHAR(SYSDATE,'YYYY/MM/DD') -> 2003/01/23
TO_CHAR(SYSDATE,'YYYYMMDD') -> 20030123

※ 반대로 처리할때는 TO_DATE함수를 사용하면 되죠~

※ ORACLE에서 숫자를 처리할때는
TO_CHAR(2500000,'L9,999,999') -> w2,500,000
TO_CHAR(2500000,'9,999,999.99') -> 2,500,000.00

※ 반대로 처리할때는 TO_NUMBER함수를 사용하면 되죠~
※ 이 외에도 활용할 수있는 용도가 무지 많습니다.

※ MSSQL에서 날짜를 처리할때는
CONVERT(VARCHAR(10),GETDATE(),120) -> 2003-01-23
CONVERT(VARCHAR(10),GETDATE(),111) -> 2003/01/23
CONVERT(VARCHAR(8),GETDATE(),112) -> 20030123

※ MSSQL에서 숫자를 처리할때는
CONVERT(varchar(20), convert(money,2500000),1) -> 2,500,000.00


출처 :
DBMS별 날짜 포맷변환

1. DBMS 별 시간, 날짜 조회 쿼리

Oracle

select sysdate from dual; 날짜+시분초 까지 조회가능
select current_timestamp from dual; 날짜+밀리초+시간존 까지 조회

MS SQL

select getdate() 날짜 + 밀리초 단위까지 조회가능

DB2 UDB

select current timestamp from sysibm.sysdummy1 날짜+밀리초까지 조회select current date from sysibm.sysdummy1 날짜만 조회
select current time from sysibm.sysdummy1 밀리초 단위시간조회



2. DBMS 별 default date format

Oracle

MS SQL

YYY/MM/DD HH:MI:SS(한글)
MM-DD-YYYY HH:MI:SS(영어)

DB2 UDB

YYYY-MM-DD-HH:MI:SS.MMMMMM (TIMESTAMP 타입)
YYYY-MM-DD (DATE 타입)
HH:MI:SS.MMMMMM (TIME 타입)



3. 날짜 포맷 변환표

형식

RDBMS

변환 문법

'YYYY.MM.DD'

Oracle


TO_CHAR(date_exp, 'YYYY.MM.DD')

MSSQL


CONVERT(VARCHAR, date_exp, 102)

DB2


REPLACE(CHAR(DATE(date_exp),ISO), '-', '.')

Oracle


TO_CHAR(date_exp, 'HH:MI:SS')


MSSQL

CONVERT(VARCHAR, date_exp, 108)


DB2

CHAR(TIME(date_exp) , JIS )


Oracle

TO_CHAR(date_exp, 'YYYY/MM/DD')


MSSQL

CONVERT(VARCHAR, date_exp, 111)


DB2

REPLACE(CHAR(DATE(date_exp), ISO), '-', '/')


Oracle

TO_CHAR(date_exp, 'YYYYMMDD')


MSSQL

CONVERT(VARCHAR, date_exp, 112)


DB2

CHAR(DATE(date_exp))


Oracle

TO_CHAR(date_exp, 'HH24:MI:SS')


MSSQL

CONVERT(VARCHAR(8), date_exp, 114)


DB2

CHAR(TIME(date_exp) )


Oracle

TO_CHAR(date_exp, 'YYYY.MM.DD HH24:MI')


MSSQL

CONVERT(VARCHAR, date_exp, 102) + ' ' + CONVERT(VARCHAR(5), date_exp, 114)


DB2

REPLACE(CHAR(DATE(date_exp), ISO), '-', '.') || CAST( TIME(date_exp) AS CHAR(5))



Oracle

TO_CHAR(date_exp, 'YYYY/MM/DD HH24:MI:SS')


MSSQL

CONVERT(VARCHAR, date_exp, 111) + ' ' + CONVERT(VARCHAR(8), date_exp, 114)


DB2

REPLACE(CHAR(DATE(date_exp), ISO), '-', '/') || CAST( TIME(date_exp))



Oracle/PLSQL: To_Date Function

In Oracle/PLSQL, the to_date function converts a string to a date.

The syntax for the to_date function is:

to_date( string1, [ format_mask ], [ nls_language ] )

string1 is the string that will be converted to a date.

format_mask is optional. This is the format that will be used to convert string1 to a date.

nls_language is optional. This is the nls language used to convert string1 to a date.


The following is a list of options for the format_mask parameter. These parameters can be used in many combinations.

ParameterExplanation
YEARYear, spelled out
YYYY4-digit year
YYY
YY
Y
Last 3, 2, or 1 digit(s) of year.
IYY
IY
I
Last 3, 2, or 1 digit(s) of ISO year.
IYYY4-digit year based on the ISO standard
RRRRAccepts a 2-digit year and returns a 4-digit year.
A value between 0-49 will return a 20xx year.
A value between 50-99 will return a 19xx year.
QQuarter of year (1, 2, 3, 4; JAN-MAR = 1).
MMMonth (01-12; JAN = 01).
MONAbbreviated name of month.
MONTHName of month, padded with blanks to length of 9 characters.
RMRoman numeral month (I-XII; JAN = I).
WWWeek of year (1-53) where week 1 starts on the first day of the year and continues to the seventh day of the year.
WWeek of month (1-5) where week 1 starts on the first day of the month and ends on the seventh.
IWWeek of year (1-52 or 1-53) based on the ISO standard.
DDay of week (1-7).
DAYName of day.
DDDay of month (1-31).
DDDDay of year (1-366).
DYAbbreviated name of day.
JJulian day; the number of days since January 1, 4712 BC.
HHHour of day (1-12).
HH12Hour of day (1-12).
HH24Hour of day (0-23).
MIMinute (0-59).
SSSecond (0-59).
SSSSSSeconds past midnight (0-86399).
FFFractional seconds. Use a value from 1 to 9 after FF to indicate the number of digits in the fractional seconds. For example, 'FF4'.
AM, A.M., PM, or P.M.Meridian indicator
AD or A.DAD indicator
BC or B.C.BC indicator
TZDDaylight savings information. For example, 'PST'
TZHTime zone hour.
TZMTime zone minute.
TZRTime zone region.


Applies To:

  • Oracle 8i, Oracle 9i, Oracle 10g, Oracle 11g


For example:

to_date('2003/07/09', 'yyyy/mm/dd')would return a date value of July 9, 2003.
to_date('070903', 'MMDDYY')would return a date value of July 9, 2003.
to_date('20020315', 'yyyymmdd')would return a date value of Mar 15, 2002.

'프로그래밍??? > 오라클' 카테고리의 다른 글

ORA-01403: no data found 대처 SQL문  (0) 2012.04.06
오라클 날짜형 함수  (0) 2012.04.05
오라클의 TRUNC 함수  (0) 2012.04.05
Native Dynamic SQL의 이해와 예제  (0) 2012.04.04
SQL%ROWCOUNT 편리함 ^^  (0) 2012.04.04


- 원하는 소수점 자리수 만큼만 보여주고 나머지는 없애버린다.

- EX) TRUNC(12.345, 2) => 12.34 (소수점 2자리만 보여준다)
TRUNC(12.345) => 12 (소수점 자릿수를 지정하지 않으면 정수만 보여준다.)
TRUNC('2004-05-33', 'MONTH') => '2004-05-01' (월을 기준으로 1일로 돌아온다)
TRUNC('2004-05-12', 'YEAR') => '2004-01-01' (년을 기준으로 1월 1일로 돌아온다)

'프로그래밍??? > 오라클' 카테고리의 다른 글

오라클 날짜형 함수  (0) 2012.04.05
오라클 DATE 관련 함수  (0) 2012.04.05
Native Dynamic SQL의 이해와 예제  (0) 2012.04.04
SQL%ROWCOUNT 편리함 ^^  (0) 2012.04.04
PLSQL문법 정리  (730) 2012.04.04

출처 :http://okjsp.pe.kr/seq/12984

52.32.10.46
=================================================================
Oracle8i : Dynamic SQL (Native Dynamic SQL)
=================================================================

DBMS_SQL package을 사용하여 compile 시에 고정되어지는 제한을 극복
하며 Dynamic SQL statement을 구현할 수 있다.

Oracle 8i에서의 Dynamic SQL은 두가지 방법이 있다.첫번째 방법은
"EXECUTE IMMEDIATE" 절을 사용하여 embedded dynamic sql을 구현하는
것이고, 두번째 방법은 선언되어지는 것 대신에 실행시에 문장을 보내는
ref cursor의 확장된 개념으로 query를 위해 사용되어지는 방법이다.

방법 1: EXECUTE IMMEDIATE
----------------------------

Syntax:
EXECUTE IMMEDIATE dynamic_sql_string
[INTO {define_var1 [, define_var2] ... | plsql_record }]
[USING [IN | OUT | IN OUT] bind_arg1 [,
[IN | OUT | IN OUT] bind_arg2] ...];


예제:
--------

(i) DDL문 실행. bind variable을 허용하지 않는다.

declare
str varchar2(200);
begin
str := 'create table msg (msg varchar2(120))';
EXECUTE IMMEDIATE str;
end;

(ii) bind variable을 사용하지 않는 non-query DML문 실행 예.

declare
str varchar2(200);
begin
str := 'insert into msg values (''Hello'')';
EXECUTE IMMEDIATE str;
end;

(iii) bind variable을 사용하지 않는 non-query DML문 실행 예.
variable은 default로 IN bind이므로 IN, OUT mode을 나타낼
필요는 없다.

declare
str varchar2(200);
val varchar2(20);
begin
str := 'insert into msg values (:b1)';
val := 'Bye';
EXECUTE IMMEDIATE str USING val;
end;

(iv) bind variable을 이용하여 single row select을 실행하고,
single define variable에 fetch하는 예.

declare
str varchar2(200);
val varchar2(20);
ret varchar2(20);
begin
str := 'select msg from msg where msg = :b1';
val := 'Hello';
EXECUTE IMMEDIATE str INTO ret USING val;
dbms_output.put_line('Value fetched from table: '||ret);
end;

Result:

Value fetched from table: Hello

(v) (iv)예와 같은 select문을 수행하며 , PL/SQL record type에 fetch하는 예.

declare
str varchar2(200);
val varchar2(20);
ret msg%rowtype;
begin
str := 'select msg from msg where msg = :b1';
val := 'Hello';
EXECUTE IMMEDIATE str INTO ret USING val;
dbms_output.put_line('Value fetched from table: '||ret.msg);
end;

Result:

Value fetched from table: Hello

(vi) returning절을 포함한 delete문을 수행하는 예. 이 경우에는 OUT mode로
선언된 bind variable이 존재해야 한다. delete된 row을 알기 위해서는
sql%rowcount을 사용하며, 모든 sql% attribute가 유효하다.

declare
str varchar2(200);
val varchar2(20);
ret varchar2(20);
begin
val := 'Bye';
str := 'delete from msg where msg = :b1 returning msg into :b2';
EXECUTE IMMEDIATE str USING val, OUT ret;
dbms_output.put_line('Deleted '||sql%rowcount||
' row(s) with value: '||ret);
end;

Result:

Deleted 1 row(s) with value: Bye

(vii) error을 check하면서 stored function을 만들고 만들어진 function을
실행하며, function은 return type으로 OUT bind variable이 제공된다.

declare
str varchar2(200);
-- Declare an exception to trap "compiled with errors"
compile_warn exception;
pragma exception_init(compile_warn,-24344);
val number;
ret number;
begin
begin
-- A deliberate error (spelling of number)
str := 'create or replace function doubleit (p1 in umber)'||
' return number as begin return p1*2; end;';
EXECUTE IMMEDIATE str;
exception
when compile_warn then
-- Correct and reexecute
str := replace(str,'in umber','in number');
EXECUTE IMMEDIATE str;
when others then raise;
end;

-- Call the stored function
str := 'begin :b1 := doubleit(:b2); end;';
val := 30;
EXECUTE IMMEDIATE str USING OUT ret, IN val;
dbms_output.put_line('Result of '||val||' doubled is '||ret);
end;

Result:

Result of 30 doubled is 60

(viii) (vii)예와 같은 function을 새로운 CALL 절을 이용하여 실행한다.

declare
str varchar2(200);
val number;
ret number;
begin
-- Call the stored function
str := 'CALL doubleit(:b2) INTO :b1';
val := 30;
EXECUTE IMMEDIATE str USING IN val, OUT ret;
dbms_output.put_line('Result of '||val||' doubled is '||ret);
end;

Result:

Result of 30 doubled is 60

(ix) 중복된 place holder가진 SQL문을 실행하는 예.

declare
str varchar2(200);
val_str varchar2(20);
val_num number;
ret number;
begin
-- DML : 이 경우는 SQL문으로 bind variable 수만큼의 place holder
-- 가 필요하다.
str := 'insert into msg values (:b1||'' ''||:b1)';
val_str := 'Hello';
EXECUTE IMMEDIATE str USING val_str, val_str;

-- PL/SQL 에서는 bind variable 수만큼의 place holder가 필요하지 않다.
str := 'begin :b1 := doubleit(:b2+:b2); end;';
val_num := 30;
EXECUTE IMMEDIATE str USING OUT ret, IN val_num;
dbms_output.put_line('Result of '||val_num||' quadrupled is '
||ret);
end;

Result:

Result of 30 quadrupled is 120

(x) NOCOPY parameter을 가진 stored procedure을 부르는 예.

create or replace procedure add_stars (p1 in varchar2,
p2 out NOCOPY varchar2) as
begin
p2 := p1||'***';
end;

NOCOPY parameter는 version 8.1에서 소개되었다. value에 의해서기 보다는
reference에 의해 전달되어지는 output parameter이며, 성능을 증가시킬뿐만
아니라 메모리를 절약할 수 있다. value에 의해 전달되어지는 parameter처럼
bind variable이 선언되어진다.

declare
str varchar2(100) := 'call add_stars(:b1,:b2)';
in_str varchar2(20) := 'Hello World';
out_str varchar2(20);
begin
EXECUTE IMMEDIATE str USING IN in_str, OUT out_str;
dbms_output.put_line(out_str);
end;

Result:

Hello World***

방법 2: ref cursor
----------------------

Syntax:
OPEN cursor_var FOR dynamic_query_string
[USING bind_arg1 [, bind_arg2] ...];


예 제 :
--------

다음의 예제를 수행하기 전에 수행되어질 사항:

create table msg (msg varchar2(120));
insert into msg values ('Hello');
insert into msg values ('Bye');

Weak: type my_cur_type is ref cursor;
Strong: type my_cur_type is ref cursor return emp%rowtype;

(i) bind 없이 cursor을 open하는 예.

declare
type my_curs_type is REF CURSOR; -- must be weakly typed
curs my_curs_type;
str varchar2(200);
ret varchar2(20);
begin
str := 'select msg from msg';
-- No placeholders so no USING clause
OPEN curs FOR str;
loop
FETCH curs INTO ret;
exit when curs%notfound;
dbms_output.put_line(ret);
end loop;
CLOSE curs;
end;

Result:

Hello
Bye

(ii) bind variable을 사용하여 cursor을 open하고 single row을 fetch하는 예.

declare
type my_curs_type is REF CURSOR; -- must be weakly typed
curs my_curs_type;
str varchar2(200);
ret varchar2(20);
val varchar2(20);
begin
str := 'select msg from msg where msg = :b1';
val := 'Bye';
OPEN curs FOR str USING val;
FETCH curs INTO ret;
dbms_output.put_line('Value fetched from table: '||ret);
CLOSE curs;
end;

Result:

Value fetched from table: Bye

(iii) 새로운 bulk collect 을 이용하여 한번에 여러 row을 fetch하는 예.

declare
str varchar2(200);
type my_curs_type is REF CURSOR; -- must be weakly typed
curs my_curs_type;

-- Use a nested table to fetch into. This could equally be
-- a VARRAY or index by table.
type string_tab is table of varchar2(20);
ret_tab string_tab; -- don't need to initialise, fetching
-- will do this automatically
begin
str := 'select msg from msg';
OPEN curs FOR str;
FETCH curs BULK COLLECT INTO ret_tab;
dbms_output.put_line('Array fetch: ');
for i in 1..curs%rowcount loop
dbms_output.put_line(ret_tab(i));
end loop;
CLOSE curs;
end;

Result:

Array fetch:
Hello
Bye


Further Information
-------------------

PL/SQL User's Guide and Reference, Chapter 10.


from oracle

白面書生

'프로그래밍??? > 오라클' 카테고리의 다른 글

오라클 DATE 관련 함수  (0) 2012.04.05
오라클의 TRUNC 함수  (0) 2012.04.05
SQL%ROWCOUNT 편리함 ^^  (0) 2012.04.04
PLSQL문법 정리  (730) 2012.04.04
SQLPLUS에서 외부 스크립트 실행하기  (0) 2012.04.04