Oracle/PL/SQL2012. 5. 10. 15:45

LONG 타입을 VARCHAR2 타입으로 변환해보자.


예제를 위해 아래와 같이 테이블을 생성하자.

DROP TABLE t1 PURGE;
CREATE TABLE t1 (c1 LONG);

DECLARE
    v1    LONG := RPAD ('1', 4000, '1') || RPAD ('2', 4000, '2') || RPAD ('3', 4000, '3') || RPAD ('4', 4000, '4');
BEGIN
    INSERT INTO t1 VALUES (v1);
    COMMIT;
END;
/

 

아래 함수는 NDS 방식을 사용했다.

CREATE OR REPLACE FUNCTION f1 (
    i_owner          IN    VARCHAR2
  , i_table_name     IN    VARCHAR2
  , i_column_name    IN    VARCHAR2
  , i_rowid          IN    ROWID
  , i_offset         IN    NUMBER DEFAULT 0
)
    RETURN VARCHAR2
IS
    l_sql_text    VARCHAR2(32767);
    l_result      VARCHAR2(32767);
BEGIN
    l_sql_text := q'[SELECT %COLUMN_NAME% FROM %OWNER%.%TABLE_NAME% WHERE ROWID = :v1]';
    l_sql_text := REPLACE (l_sql_text, '%OWNER%', i_owner);
    l_sql_text := REPLACE (l_sql_text, '%TABLE_NAME%', i_table_name);
    l_sql_text := REPLACE (l_sql_text, '%COLUMN_NAME%', i_column_name);

    EXECUTE IMMEDIATE l_sql_text INTO l_result USING i_rowid;

    RETURN SUBSTR (l_result, 1 + i_offset, 4000);
END;
/

 

아래 함수는 DBMS_SQL 패키지를 사용했다.

CREATE OR REPLACE FUNCTION f2 (
    i_owner          IN    VARCHAR2
  , i_table_name     IN    VARCHAR2
  , i_column_name    IN    VARCHAR2
  , i_rowid          IN    ROWID
  , i_offset         IN    NUMBER DEFAULT 0
)
    RETURN VARCHAR2
IS
    l_sql_text        VARCHAR2(32767);
    l_c               INTEGER := DBMS_SQL.OPEN_CURSOR;
    l_r               INTEGER;
    l_result          VARCHAR2(32767);
    l_result_length   NUMBER;
BEGIN
    l_sql_text := q'[SELECT %COLUMN_NAME% FROM %OWNER%.%TABLE_NAME% WHERE ROWID = :v1]';
    l_sql_text := REPLACE (l_sql_text, '%OWNER%', i_owner);
    l_sql_text := REPLACE (l_sql_text, '%TABLE_NAME%', i_table_name);
    l_sql_text := REPLACE (l_sql_text, '%COLUMN_NAME%', i_column_name);

    DBMS_SQL.PARSE (l_c, l_sql_text, DBMS_SQL.native);
    DBMS_SQL.BIND_VARIABLE (l_c, ':v1', i_rowid);
    DBMS_SQL.DEFINE_COLUMN_LONG (l_c, 1);

    l_r := DBMS_SQL.EXECUTE (l_c);

    IF (DBMS_SQL.FETCH_ROWS (l_c) > 0) THEN
        DBMS_SQL.COLUMN_VALUE_LONG (l_c, 1, 4000, i_offset, l_result, l_result_length);
    END IF;

    DBMS_SQL.CLOSE_CURSOR (l_c);
    RETURN l_result;
END f2;
/

 

아래는 두 함수를 사용한 결과다.

SELECT f1 ('TUNA', 'T1', 'C1', ROWID) AS c1 FROM t1;

C1
--------------------------------------------------
11111111111111111111111111111111111111111111111111
...
1개의 행이 선택되었습니다.


SELECT f1 ('TUNA', 'T1', 'C1', ROWID, 8000) AS c1 FROM t1;

C1
--------------------------------------------------
33333333333333333333333333333333333333333333333333
...
1개의 행이 선택되었습니다.


SELECT f2 ('TUNA', 'T1', 'C1', ROWID) AS c1 FROM t1;

C1
--------------------------------------------------
11111111111111111111111111111111111111111111111111
...
1개의 행이 선택되었습니다.


SELECT f2 ('TUNA', 'T1', 'C1', ROWID, 12000) AS c1 FROM t1;
  
C1
--------------------------------------------------
44444444444444444444444444444444444444444444444444
...
1개의 행이 선택되었습니다.


'Oracle > PL/SQL' 카테고리의 다른 글

DBMS_UTILITY.EXPAND_SQL_TEXT 프로시저  (0) 2014.04.19
REFERENCE CURSOR 예제  (0) 2013.09.01
한글 자소 분리  (0) 2012.06.22
DBMS_UTILITY.FORMAT_ERROR_BACKTRACE 예제  (0) 2012.05.11
EXECUTE IMMEDIATE 예제  (0) 2012.04.30
Posted by 정희락_