create or replace function get_member_cmcode( p_cate varchar2, p_code varchar2, p_retfield varchar2)
return varchar2 as
l_str varchar2(1000);
nstr varchar2(30);
begin
l_str:='';
for emp_cur in (select * from cm_code where cate=p_cate and code=p_code) loop
-- l_str := l_str||'-'||emp_cur.codenm;
-->
l_str := l_str||'-'||emp_cur.[p_retfield]; <- 커서필드를 파라미터로 넘기는 방법을 못찾았습니다.
end loop;
if (substr(l_str,1,1)='-') then
l_str := substr(l_str,2,length(l_str)-1);
end if;
return l_str;
end;
/
이 함수에서 세번째 파라미터로 "codenm" 이라는 필드를 조회할 경우 "emp_cur.[p_retfield]" 는 안되더군요.
임의의 필드명을 이 함수로 전달해서 조회하는 방법이 없을까요?
하다못해 조회 레코드(커서)의 몇번째 필드값(select code, codenm from cm_code 일때 두번째인 codenm을 리턴가능해도 상관없습니다)
function 내용이 문자열 합치는 함수네요. listagg등의 오라클 함수로 사용하시는 게 나을 듯하네요.
http://www.gurubee.net/article/55512
select listagg(필드명,'-') within group(order by 정렬기준컬럼) from cm_code where cate=p_cate and code=p_code
사용자 함수를 하셔야만 하는 이유가 있나요?
만약 그렇다면 커서문을 동적으로 변동되게 구현하셔야할 것 같구요.
CREATE OR REPLACE FUNCTION GET_MEMBER_CMCODE(P_CATE VARCHAR2, P_CODE VARCHAR2, P_RETFIELD VARCHAR2) RETURN VARCHAR2 AS L_STR VARCHAR2(1000); TYPE CUR IS REF CURSOR; V_SQL VARCHAR2(4000); V_TEMP VARCHAR2(100); C1 CUR; BEGIN L_STR := ''; V_SQL := 'select to_char(' || P_RETFIELD || ') from cm_code a where cate=:p_cate and code =:p_code'; OPEN C1 FOR V_SQL USING P_CATE, P_CODE; LOOP FETCH C1 INTO V_TEMP; EXIT WHEN C1%NOTFOUND; IF L_STR IS NULL THEN L_STR := V_TEMP; ELSE L_STR := L_STR || '-' || V_TEMP; END IF; END LOOP; CLOSE C1; RETURN L_STR; END;
예, 함수에 해당 리턴필드가 일정하지 않아서요.
필요한 필드값은 def1 이라는 필드가 있는데, 어떤 레코드는 "codenm" 이라는 필드이고(해당 레코드의 def1에 "codenm" 저장), 또 어떤 레코드는 "abc1" 필드이고(해당레코드의 def에 "abc1" 저장), 이렇게 필요한 필드가 가변적이다보니 리턴되는 필드가 레코드마다 "def1" 에서 가리키는 필드에 따라 다 달라야해서요.
리턴값은 항상 1개인데, for문을 쓴건 참조한 필드에서 for문을 쓴것을 참조했는데 시간이 없다보니 for문을 제거하지 못한겁니다.
항상 한개이니(pk 필드가 저 파라미터 2개입니다), 문자열을 묶을 가능성은 전혀 없고 한개 레코드를 참조하고 끝납니다.
올려주신 방법으로 하니 잘 되네요.
역시 고수이십니다.
정말 감사합니다.
즐거운 하루 되세요.
여러건이 아닌 단건이라면?
EXECUTE IMMEDIATE 을 이용하면 됩니다.
CREATE OR REPLACE FUNCTION get_member_cmcode (p_cate VARCHAR2, p_code VARCHAR2, p_retfield VARCHAR2) RETURN VARCHAR2 IS l_str VARCHAR2(100); v_sql VARCHAR2(100); BEGIN v_sql := 'SELECT ' || p_retfield || ' FROM cm_code WHERE cate = :p_cate AND code = :p_code'; EXECUTE IMMEDIATE v_sql INTO l_str USING p_cate, p_code; RETURN l_str; END; /