database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
PostgreSQL
Firebird
Oracle
Informix
Sybase
MS-SQL
ㆍDB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
DB2 Q&A 3469 게시물 읽기
No. 3469
db2쿼리...
작성자
초보입니다(kimsh520)
작성일
2017-08-08 16:06
조회수
5,014

SELECT A.DEP_ID, A.PAR_DEP_ID, A.DEP_TITLE, GET_PAR_DEP_TITLE(A.PAR_DEP_ID) AS PAR_DEP_TITLE, A.DEP_DESC, A.DEP_TP_CD, B.DISPLAY_NM AS DEP_TP_CD_NM, A.DISPLAY_DEPTH,

A.DISPLAY_ORDER,A.CRE_ID, GET_USER_NAME(A.CRE_ID) CRE_NM,A.CRE_DT,A.UPD_ID, GET_USER_NAME(A.UPD_ID) UPD_NM, A.UPD_DT

FROM C_DEP_INFO A, C_CD_NM B

WHERE B.CD_ID = A.DEP_TP_CD

AND A.DEP_ID = 10

AND B.LANG_CD= 'ko-KR'

 

이런쿼리문을 돌리는데요

 

SQL0740N 루틴 "DB2ADMIN.GET_USER_NAME"(특정 이름 "GET_USER_NAME")이(가) MODIFIES SQL DATA 옵션으로 정의되었지만, 이는 루틴이 호출된 컨텍스트에서 유효하지 않습니다. SQLSTATE=51034

 

라는 에러가 떨어지네요...혹시 db2에서는 오라클에서 사용한 GET_USER_NAME / GET_PAR_DEP_TITLE 함수를 못쓰는건가요

이 글에 대한 댓글이 총 11건 있습니다.

안녕하세요. DB2_COMPATIBILITY_VECTOR=ORA를 설정하지 않은 상태이신가요?

로직을 올려봐주시면 참고가 될듯합니다.

정상규(pajama)님이 2017-08-08 22:59에 작성한 댓글입니다.

예 그것을 사용못하게 아예 호환기능을 빼고 db2로 전환해야되는 상황이라서요.

초보입니다(kimsh520)님이 2017-08-09 08:59에 작성한 댓글입니다.

혹시 프로시져도 오라클과는 다르게 DB2로 작성해야하는 문법이라든지 그런게 있나요

초보입니다(kimsh520)님이 2017-08-09 10:40에 작성한 댓글입니다.

db2에서는 함수내에 UPDATE, INSERT, DELETE, MERGE등 데이터 조작이 있는 경우 MODIFIES SQL DATA 절을 사용하고 테이블 함수 형태로 리턴해야합니다.

간단한 예로 아래와 같이 사용합니다.

예) 샘플 함수
CREATE OR REPLACE FUNCTION myFun (IN p_no INT,IN p_in VARCHAR(30))
RETURNS TABLE (p_no_out INT, p_in_out VARCHAR(30))
LANGUAGE SQL
MODIFIES SQL DATA
BEGIN ATOMIC
 INSERT INTO TEST (a, b) VALUES (p_no, p_in);
 RETURN SELECT a, b FROM TEST;
END @
 
 
** 샘플함수 실행
$ db2 "select * from table ( myFun (1, 'Hello DB2 fun') )"
 
P_NO_OUT    P_IN_OUT
----------- ------------------------------
          1 Hello DB2 fun
 
 
참고가 되시면 좋겠습니다.
함수 내용은 아래를 참고했습니다.
 
http://myy.haaga-helia.fi/~dbms/dbtechnet/papers/SQL_StoredRoutines.pdf
https://www.ibm.com/support/knowledgecenter/en/SSEPGG_9.7.0/com.ibm.db2.luw.apdv.routines.doc/doc/c0011177.html
정상규(pajama)님이 2017-08-09 22:39에 작성한 댓글입니다.

DROP SPECIFIC FUNCTION "GET_USER_NAME";

 

CREATE OR REPLACE FUNCTION "GET_USER_NAME" (userId NUMBER ) RETURN VARCHAR2 IS

v_user_name varchar2(100) := '';

begin

select user_nm into v_user_name from C_USER where user_id=userId;

return v_user_name;

END;

 

GET_USER_NAME에 대한 함수입니다..

위와같이 DB2에서 사용할시 문제가되는건가요;;

 

그리고 위문장을 다시 db2 에다가 create하려고하는데요 계속 DB221034E 명령이 유효한 명령행 처리기 명령이 아니므로 SQL문으로 처리되었습니다.

SQL0104N " RETURNS VARCHAR2 "다음에 예기치 않은 토큰 "IS v_user_name" 이(가)있었습니다. 예상한 토큰은""입니다 LINE NUMBER=4 SQLSTATE =42601

이렇게 뜨는데 IBM사이트에서 오류검색해도 무슨말인지모르겠고.. 도움요청드립니다..

초보입니다(kimsh520)님이 2017-08-11 11:20에 작성한 댓글입니다.
이 댓글은 2017-08-11 11:35에 마지막으로 수정되었습니다.

우선 오라클 호환모드를 사용하지 않으시면 함수 작성 syntax가 다릅니다.

그리고 오라클의 VARCHAR2 타입은 DB2는 VARCHAR로 대응합니다.

오라클의 NUMBER는 DECIMAL이나 DECFLOAT 타입을 씁니다.

보여주신 함수를 DB2 스타일로 쓴다면 아래와 같습니다.

CREATE OR REPLACE FUNCTION "GET_USER_NAME" (userId DECIMAL)
RETURNS VARCHAR(100)
BEGIN
DECLARE v_user_name varchar(100);
select user_nm into v_user_name from C_USER where user_id=userId;
RETURN v_user_name;
END
@
 
참고하세요.
정상규(pajama)님이 2017-08-11 12:53에 작성한 댓글입니다.

그럼 IS 라는 뒤에 변수선언을 해주는데 DB2는 BEGIN 안에다 변수를 설정해야하는건가요?...

그리고 예를들어

 

오라클에서는

 

BEGIN

 

v_cd := v_code_no;

v_cd1 := v_code_id;

 

이런식으로 되어있는데요 v_code_no를 v_cd로 넣어주는데..db2에서도 := 이문법이 동일한가요..아.그리고..매번감사합니다

초보입니다(kimsh520)님이 2017-08-11 13:56에 작성한 댓글입니다.
이 댓글은 2017-08-11 13:57에 마지막으로 수정되었습니다.

네 DB2는 BEGIN 안에서 변수 선언을 합니다.

그리고 변수에 값을 설정하려면 아래처럼 SET문을 사용합니다.

v_cd := v_code_no;

>> SET v_cd = v_code_no;

 

 

정상규(pajama)님이 2017-08-11 14:30에 작성한 댓글입니다.

IF UPPER(v_gub) ='MENU' THEN

 

SELECT DISPLAY_NM

INTO v_cd_nm

FROM C_MENU_DISPLAY

WHERE MENU_ACT_ID = v_cd1;

ELSEIF UPPER(v_gub) ='AC' THEN

IF LENGTH(v_cd1) = 14 THEN --->이부분 IF문으로 하면안되나요..

v_cd_nm = substr(v_cd1,1,3) || '-' || substr(v_cd1,4,2) || '-' || substr(v_cd1,6,2) || '-' || substr(v_cd1,8,7);

ELSE

v_cd_nm := v_cd1;

END IF;

END IF;

 

마지막으로요 ㅠㅠ 죄송합니다

초보입니다(kimsh520)님이 2017-08-11 14:56에 작성한 댓글입니다.
이 댓글은 2017-08-11 14:58에 마지막으로 수정되었습니다.
글쎄요 중첩으로 쓰셔도 잘 됩니다.
아래는 제가 테스트 한 내용입니다. (되는지 안되는지만 테스트했습니다)
 
CREATE OR REPLACE FUNCTION "TEST1" (userId DECIMAL)
RETURNS VARCHAR(100)
BEGIN
DECLARE v_user_name varchar(100);
IF userId = 100 THEN
select user_nm into v_user_name from C_USER where user_id=userId;
ELSEIF userId = 200 THEN
        IF userID - 1 = 199 THEN
                select 'name2' into v_user_name from C_USER;
        ELSE SET v_user_name = 'name3';
        END IF;
END IF;
RETURN v_user_name;
END
@
 
정상규(pajama)님이 2017-08-11 15:57에 작성한 댓글입니다.

아..오류가 if쪽이아닌 아래보시면

v_cd_nm을 set v_cd_nm 변수를 쓸때마다 다시 해주어야되는군요..

저는 한번 위에서 set v_cd_nm이라고 선언해주면 아래서는 그냥 v_cd_nm만 써주면되는줄알았네요;;

오라클이랑 너무 다른게많아서;;

매번감사합니다 ;

 

 

초보입니다(kimsh520)님이 2017-08-11 18:17에 작성한 댓글입니다.
[Top]
No.
제목
작성자
작성일
조회
3472쿼리좀 작성문제입니다.. [7]
초보입니다
2017-08-23
2623
3471db2 (+) [1]
초보입니다
2017-08-18
2891
3470DECFLOAT_FORMAT 에러 [1]
초보입니다
2017-08-16
2960
3469db2쿼리... [11]
초보입니다
2017-08-08
5014
3468CONNECT_BY_ISLEAF [6]
초보입니다
2017-08-03
3185
3467DB2에서 모든 프로시저및 객체들의 script를 검색할수 있는 방법이 있을까요?? [2]
GGOM
2017-06-19
2956
3447토드 DB2에서 리눅스 접속 [3]
김성수
2017-03-28
3118
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2023 DSN, All rights reserved.
작업시간: 0.052초, 이곳 서비스는
	PostgreSQL v16.1로 자료를 관리합니다