2011년 12월 11일 일요일

MS SQL Server 개발자를 위한 DB2 가이드 (3)

MS SQL Server 개발자를 위한 DB2 가이드 (3)

* 출처: http://www.kdug.kr/
* 저자: 강창성 님

개발/마이그레이션 | 2009-07-07 10:31:06
많은 기업 환경에서 단일한 DB 환경보다는 이기종 DB 환경을 운영하고 있다. 따라서 DB 개발자나 관리자는 되도록 많은 DBMS 다룰 아는 것이 업무에 도움이 된다. 특히 다양한 DBMS MS SQL Server 2000(이하 MS SQL Server) DB2 함께 비교해볼 기회는 흔치 않다.
문서가 MS SQL Server 그리고 DB2 환경에서 SQL 프로그래밍을 하는 개발자나 어느 DBMS 마이그레이션을 검토하고 있는 운영 담당자에 조금이나마 도움이 되기를 바라고 서로의 특징을 상호 비교해보면서 MS SQL Server DB2 모두 친숙해질 있는 계기가 되었으면 한다.
임시 테이블, CTE, Merge into 사용 안내
해당 세션이 DB상에서도 유지할 때만 존재하는 임시 테이블 대해서 활용을 바로 해보자. 비록 문법 부분이 약간 상이하지만 DBMS 모두 임시 테이블 생성이 가능하다. 반면에 MS SQL Server 2000에서는 CTE Merge into 문장은 DB2 이미 지원 중이지만, MS SQL Server에서는 업그레이드 버전에서 지원이 되고 있다.
[ 1] DB 임시 테이블 사용
SQL Server
DB2 UDB
CREATE TABLE #order (
prod_id INT NOT NULL PRIMARY KEY,
title_id CHAR(6) NOT NULL,
qty INT NOT NULL
)
GO
DECLARE GLOBAL TEMPORARY TABLE gbl_temp
LIKE employee
ON COMMIT DELETE ROWS
NOT LOGGED
IN usr_tbsp
SELECT * FROM #order
SELECT * FROM SESSION.gbl_temp
CREATE TABLE ##customer (
c_id INT NOT NULL PRIMARY KEY,
name VARCHAR(80) NOT NULL,
addr VARCHAR(200) NOT NULL,
tel CHAR(10) NOT NULL
)
GO
CREATE TABLE customer (
c_id INT NOT NULL PRIMARY KEY,
name VARCHAR(80) NOT NULL,
addr VARCHAR(200) NOT NULL,
tel CHAR(10) NOT NULL
)
NOT LOGGED INITIALLY
ü CTE(Common Table Expression) 형식은 MS SQL 2005에서부터 지원하고 있고, DB2에서는 일찍 사용이 가능했다.
[ 2] DB2 CTE 사용
DB2
DB2에서 오라클 형식 지원(9.5)
WITH parent (lvl, deptno, deptname,admrdept) AS
(SELECT 1 ,deptno, deptname,admrdept
FROM dept
WHERE deptno = 'E01'
UNION ALL
SELECT p.lvl + 1 ,c.deptno,c.deptname, c.admrdept
FROM dept c, parent p
WHERE p.deptno= c.admrdept
)
SELECT * FROM parent
select LEVEL, deptno, deptname,admrdept
FROM dept
START WITH DEPTNO='A00'
CONNECT BY NOCYCLE PRIOR deptno= admrdept
ü DB2에서는 오라클 형식의 재귀쿼리문(connect by 구문) 지원하는데 작업 전에 미리 오라클 호환성의 옵션을 설정해야 한다. CLP> db2set DB2_COMPATIBILITY_VECTOR=0F
[ 3] MERGE INTO 사용
MERGE INTO table_name alias // 테이블 명만 올수 있음(셀렉트 쿼리 No)
USING (table|view|subquery) alias //
일반적으로 쓰는 쿼리 Ok
ON (join condition) // where
절이라고 생각하면 (조건에 서브 OK)
WHEN MATCHED THEN //
데이터 중복 건이 있는 경우 Update
UPDATE SET col1 = val1[, col2 = val2…]
WHEN NOT MATCHED THEN //
중복 건이 없는 경우 처리 Insert
INSERT (
컬럼리스트) VALUES (값들....);
ü DB2 MERGE INTO 문은 테이터를 넣어야 테이블에 값이 이미 있으면 Update, 값이 없으면 Insert 되는 등으로 활용 가능하다. MS SQL Server 2008부터 지원이 되고 있다.

[ 4] MERGE INTO 구조문
MERGE INTO 테이블명 X
USING (SELECT P_YLD_DATE AS P_YLD_DATE
FROM SYSIBM.SYSDUMMY1
) Y
ON X.YLD_DATE = Y.P_YLD_DATE
AND X.LINE_ID = Y.P_LINE_ID
AND X.STEP_ID = Y.P_STEP_ID

WHEN MATCHED THEN

UPDATE
SET X.PKG_CODE = P_PKG_CODE
, X.ABNSTART_QTY = P_ABNSTART_QTY
WHEN NOT MATCHED THEN
INSERT
VALUES (
P_YLD_DATE , P_LINE_ID , P_STEP_ID , P_PART_ID
, P_PRIME_BATCH_YLD , CURRENT TIMESTAMP , P_ABNSTART_QTY )
DB 함수 표현식 비교
지금부터는 SQL Server DB2 함수를 연관시켜서 비교해 보도록 하자.
[ 5] DB 함수 표현식 예제
DB2
OUTPUT
VALUES 1/3 *3 * 100
0
VALUES DEC(1)/3 *3 * 100
99.999999999999999999
VALUES CAST(DEC(1)/3* 3 *100 AS DEC(6,4))
99.9999
values digits( smallint(54))
00054
values digits(int(54))
0000000054
values digits(DEC(54, 3))
054
VALUES CURRENT DATE
2009. 1. 25
VALUES REPLACE(CAST(CURRENT DATE AS VARCHAR(10)), '-', '')
20090125
VALUES CURRENT TIMESTAMP, CURRENT TIMESTAMP- 10 MINUTES
2009. 1. 25 오후 1:42:42
2009. 1. 25 오후 1:32:42
select
timestampdiff (32, char(
timestamp('2008-12-30-00.00.00')-
timestamp('2008-12-08-00.00.00')))
from sysibm.SYSDUMMY1
3
* timestampdiff 파라미터
1 = Fractions of a second 2 = Seconds 4 = Minutes
8 = Hours 16 = Days 32 = Weeks
64 = Months 128 = Quarters 256 = Years
DB 개발자들이 자주 혼동하는 DB2 날짜 표현식을 점검해보고 가보도록 하자.
[ 6] 날짜 관련 함수 매핑 (1)
SQL Server
DB2 UDB
결과
DATEPART(year, GETDATE())
YEAR(CURRENT DATE)
2009
DATEPART(quarter, GETDATE())
QUARTER(CURRENT DATE)
1
DATEPART(month, GETDATE())
MONTH(CURRENT DATE)
1
DATEPART(dayofyear, GETDATE())
DAYOFYEAR(CURRENT DATE)
25
DATEPART(day, GETDATE())
DAY(CURRENT DATE)
25
DATEPART(week, GETDATE())
WEEK(CURRENT DATE)
5
DATEPART(weekday, GETDATE())
DAYOFWEEK(CURRENT DATE)
1
DATEPART(hour, GETDATE())
HOUR(CURRENT TIME)
9
DATEPART(minute, GETDATE())
MINUTE(CURRENT TIME)
40
DATEPART(second, GETDATE())
SECOND(CURRENT TIME)
29
* VALUES CURRENT TIMESTAMP => 2009. 1. 25 오전 9:40:51
[ 7] 날짜 관련 함수 매핑 (2)
형식
RDBMS
변환 문법
'YYYY.MM.DD'
MSSQL
CONVERT(VARCHAR, date_exp, 102)
DB2
REPLACE(CHAR(DATE(date_exp),ISO), '-', '.')
'HH:MI:SS'
MSSQL
CONVERT(VARCHAR, date_exp, 108)
DB2
CHAR(TIME(date_exp) , JIS )
'YYYY/MM/DD'
MSSQL
CONVERT(VARCHAR, date_exp, 111)
DB2
REPLACE(CHAR(DATE(date_exp), ISO), '-', '/')
'YYYYMMDD'
MSSQL
CONVERT(VARCHAR, date_exp, 112)
DB2
CHAR(DATE(date_exp))
'HH24:MI:SS'
MSSQL
CONVERT(VARCHAR(8), date_exp, 114)
DB2
CHAR(TIME(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))
'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))
저장 프로시저, 사용자 정의함수 활용 비교
[ 8] 저장 프로시저 문법 비교 (1)
T-SQL
SQL PL
DECLARE @varname datatype =
defaultvalue
DECLARE varname datatype DEFAULT
defaultvalue;
SELECT @var1=value
SET var1 = value;
SELECT @var1=colname FROM table
WHERE…
SET var1 = ( SELECT colname FROM table
WHERE…);
SELECT @v1=col1,@v2=col2,@v3=col3
FROM table...
SELECT col1,col2,col3 INTO v1,v2,v3
FROM table...
SELECT column_alias = column_name,…
SELECT column_name AS column_alias, ...
WHILE expression BEGIN … END
WHILE expression DO … END WHILE;
CONTINUE
ITERATE
BREAK
LEAVE loop_label
IF (…) BEGIN … END ELSE …
IF (…) THEN … ELSE … END IF;
[ 9] 프로시저 문법 비교 (2)
T-SQL
SQL PL
EXECUTE (‘INSERT INTO t1 VALUES(2)’)
INSERT INTO t1 VALUES (2); OR
EXECUTE IMMEDIATE (‘INSERT INTO t1
VALUES(2)’);
EXECUTE procname( parm1,parm2,...)
CALL procname( parm1,parm2,…);
EXECUTE @retval=procname(
parm1,parm2,…)
CALL procname( parm1,parm2,…);
GET DIAGNOSTICS retval =
RETURN_STATUS;
RETURN <int_value>
RETURN < int_expr>;
GOTO <label>
GOTO <lable>
PRINT
사용자 정의 함수 PUT_LINE()
RAISERROR, @@ERROR, @@SQLSTATUS
SQLCODE , SQLSTATE, SIGNAL
@@ROWCOUNT
GET DIANOSTICS rc = ROW_COUNT;
@@TRANCOUNT
-
[ 10] DB별로 저장 프로시저 생성 직접 해당 프로시저를 실행해 보기
SQL Server
DB2 UDB
CREATE PROC get_cheap_books
@cost money = 20.00
AS
SELECT title, price FROM redbooks WHERE price < @cost
GO
CREATE PROCEDURE get_cheap_books ( )
LANGUAGE SQL
READS SQL DATA
DYNAMIC RESULT SETS 1
BEGIN
DECLARE default_cost DECIMAL(19,4) DEFAULT 20.00;
SET default_cost = v_cost;
DECLARE temp_cursor CURSOR WITH HOLD WITH RETURN TO CLIENT
FOR SELECT title, price
FROM redbooks
WHERE price < default_cost;
OPEN temp_cursor;
END;
EXE get_cheap_books
CALL get_cheap_books ( )
[ 11] DB2 저장 프로시저에서 DYNAMIC RESULT 옵션 사용하기
SQL Server
DB2 UDB
CREATE PROCEDURE titles_cursor
@cur_titles CURSOR VARYING OUTPUT
AS
SET @cur_titles = CURSOR FORWARD_ONLY STATIC FOR
SELECT book_no, title FROM redbooks
OPEN @titles_cursor
GO
CREATE PROCEDURE titles_cursor()
LANGUAGE SQL
READS SQL DATA
DYNAMIC RESULT SETS 1
BEGIN
DECLARE titles_cursor CURSOR WITH HOLD WITH RETURN TO CLIENT
FOR SELECT book_no, title
FROM redbooks;
OPEN titles_cursor;
END;
DB 사용자 정의 함수 간단 예제
[ 12] 사용자 정의 함수(UDF) 비교
SQL SERVER
DB2 UDB
CREATE FUNCTION avg_price(@brand_id int)
RETURNS money
AS
BEGIN
RETURN ( SELECT avg(price)
FROM redbooks
WHERE brand_id = @brand_id)
END
GO
CREATE FUNCTION avg_price (v_brand_id INTEGER)
RETURNS DECIMAL(19,4)
LANGUAGE SQL
READS SQL DATA
RETURN ( SELECT AVG(price)
FROM redbooks
WHERE brand_id = v_brand_id)
!
CREATE FUNCTION books_by_brand (@brand_id int)
RETURNS TABLE
AS
RETURN ( SELECT book_no, title, price
FROM redbooks
WHERE brand_id = @brand_id)
GO
CREATE FUNCTION books_by_brand (v_brand_id INTEGER)
RETURNS TABLE(
book_no CHAR(10),
title VARCHAR(80),
price DECIMAL(19,4))
LANGUAGE SQL
READS SQL DATA
BEGIN ATOMIC
RETURN ( SELECT book_no,title,price
FROM redbooks
WHERE brand_id = v_brand_id );
END
에러 처리 코드 안내
[ 13] 에러 코드문
SQL SERVER
DB2
@fetch_status
0 : Fetch 문이 정상적으로 실행되었을 경우
-1 : Fetch문이 실패하거나 범위에서 벗어났을 경우
-2 : 인출된 행이 없을 경우
SQLCODE SQLSTATE
0 00000: SQL Execute OK
SQLSTATE 00000: SQL문의 실행이 성공했으며 어떤 유형의 경고 또는 예외 상태도 발생하지 않았습니다.

100 02000: No Data Found
SQLSTATE 02000: 다음 예외 하나가 발생했습니다. SELECT INTO 또는 INSERT문의 부속선택의 결과가 테이블이었습니다. 탐색한 UPDATE 또는DELETE문에서 식별된 수가 0이었습니다. FETCH문에서 참조된 커서의 위치가 결과 테이블의 마지막 다음입니다.
CLP> db2 ? "sql100n" -- SQLCODE 조회
CLP> db2 ? “02000”-- SQLSTATE 조회
지금까지 MS SQL Server DB2 차이점을 비교해 보면 조금 다른 하지만 많은 부분에 있어서 유사한 특징도 많이 공유하고 있다는 점을 느낄 있을 것이다.
여기까지 읽어보고 MS SQL Server DB2 동시에 다루거나 또는 특정의 DB 마이그레이션 하는 있어서 부담감을 조금 덜고 좀더 친숙하게 다가서는 계기를 되었기를 희망해본다.
[참고 자료]
- Microsoft SQLServer to DB2 Migration Comparison White Paper
- Microsoft SQL Server to IBM DB2 UDB Conversion Guide
- Leverage your Microsoft SQL Server 2000 Skills to Learn DB2 UDB Version 8
§ http://users.handysoft.co.kr/~jelong/dateformat.htm

댓글 없음:

댓글 쓰기