2011-09-28 45 views
1

我有返回一个大的数据时,它返回下列错误以下PLSQL功能。甲骨文PLSQL函数抛出PL/SQL:数字或值错误:字符串缓冲区太小,用于返回大数据

ORA-06502: PL/SQL: numeric or value error: character string buffer too small 

修饰PLSQL功能

CREATE OR REPLACE FUNCTION FRDUSER.FRD_TELECOP_DYN_REP_SELECT_OPT (p_select IN VARCHAR2) 
    RETURN CLOB 
AS 
-- v_temp   CLOB; 
    v_out   CLOB; 
    TYPE RefCurTyp IS REF CURSOR;  
-- len  BINARY_INTEGER; 
    v_cursor   RefCurTyp; 
    c_key   VARCHAR2 (1000); 
    c_value   VARCHAR2 (1000); 
    separator  VARCHAR2(3); 

BEGIN 

    OPEN v_cursor FOR p_select; 

    -- Fetch rows from result set one at a time: 
    separator := '';  

    LOOP  

     FETCH v_cursor INTO c_key,c_value;   
     EXIT WHEN v_cursor%NOTFOUND; 

    --  dbms_lob.createtemporary(v_out, TRUE); 
    --  dbms_lob.open(v_out, dbms_lob.lob_readwrite); 
     v_out := v_out || separator || c_key || ',' || c_value; 
    --  dbms_lob.append(v_out, v_temp); 
     separator := ':'; 

    END LOOP; 

    -- Close cursor: 
    CLOSE v_cursor; 
    RETURN (v_out); 
END; 
/

我执行如下的功能,

  SELECT CASE 
       WHEN OPTIONS_TYPE = 'S' THEN OPTIONS_VALUES 
       WHEN OPTIONS_TYPE = 'D' THEN TO_CLOB(FRD_TELECOP_DYN_REP_SELECT_OPT (OPTIONS_VALUES)) 
       END 
     FROM FRD_REP_FW_REP_TEMPLATES A, FRD_REP_FW_TEMPLATES B 
     WHERE A.REP_ID=1123 AND A.TEMP_ID=B.TEMP_ID 
     ORDER BY A.REP_TEMP_ID ASC 

,当我跑在上面的SQL查询它抛出以下错误 ORA-00932 :不一致的数据类型:预计CHAR得到CLOB

到SQL函数(options_values)该参数包含SQL查询。

+0

确定。你能发布完整的错误堆栈,包括抛出错误的行号吗?你能指出你的代码的哪一行正在抛出错误吗?你能让我们知道你使用的是什么版本的Oracle吗? –

+0

@Justin:对于修改的PLSQL,sql查询返回此错误(错误ORA-22835:缓冲区对于CLOB到CHAR或BLOB到RAW转换(实际:34743,最大值:4000)太小) –

回答

4

我怀疑你的过于复杂的逻辑一点。你可能只需要像这样(假设你确实需要在动态传递查询到的功能)

SQL> create table clob_test (
    2 key varchar2(100), 
    3 val varchar2(100) 
    4 ); 

Table created. 

SQL> insert into clob_test 
    2 select level, dbms_random.string('A', 100) 
    3  from dual 
    4 connect by level <= 10000; 

10000 rows created. 

SQL> ed 
Wrote file afiedt.buf 

    1 create or replace function return_clob 
    2 return clob 
    3 as 
    4 v_out clob; 
    5 v_sql varchar2(1000) := 'select key, val from clob_test'; 
    6 v_key varchar2(100); 
    7 v_val varchar2(100); 
    8 v_rc sys_refcursor; 
    9 begin 
10 open v_rc for v_sql; 
11 loop 
12  fetch v_rc into v_key, v_val; 
13  exit when v_rc%notfound; 
14  v_out := v_out || v_key || ', ' || v_val; 
15 end loop; 
16 return v_out; 
17* end; 
SQL>/

Function created. 

SQL> select return_clob from dual; 

RETURN_CLOB 
-------------------------------------------------------------------------------- 

1, tzGWFXwKLgrRTGzTGbWMYMjVniIVMmCuGYGYydcrArHPRLExoFAJsZVhhPrRKyERExqRkbLGSebqX 
<< more lob data removed>> 
+0

感谢您的建议。我试过你的代码,它会抛出ORA-06502:PL/SQL:数值或值错误:原始变量长度太长 ORA-06512:在“FRDUSER.FRD_TELECOP_DYN_REP_SELECT_OPT”,第20行。我有大约431行要并置。 –

+0

@SureshS - 您试图在“V_OUT”中放入多少数据?显然,我选择的1000有点武断。如果你想把超过1000个字节放入变量中,你需要使用更长的字节。如果你想在变量中放入超过4000个字节,你需要使用一个LOB。 –

+0

我想在V_OUT中放置大约90000字节的数据。我需要使用DBMS_LOB函数来写入v_out吗? –

1

Oracle

解码:

If expr and search are character data, then Oracle compares them using nonpadded comparison semantics. expr, search, and result can be any of the datatypes CHAR, VARCHAR2, NCHAR, or NVARCHAR2. The string returned is of VARCHAR2 datatype and is in the same character set as the first result parameter.

所以你试图强制解码的结果是一个clob,它不会。

你有没有试过case statement代替解码? (我没有,但值得一试;)

+0

我试图使用case语句,但它抛出ORA-00932:不一致的数据类型:期望的CHAR获得CLOB –

相关问题