需要帮助将clob转换为oracle中的varchar,我必须在oracle的case函数中使用varchar

时间:2013-08-19 13:20:53

标签: oracle pivot

我有一个要求,我必须从clob数据类型获取数据,转换为varchar2,为oracle 10g创建一个数据透视。

我正在使用以下

select max(case 
             when key='abc' 
             then dbms_lob.substr(value) 
           end) as data_abc 
  from table.

如果值小于4000,则上述查询正常工作,但如果大于4000则显示缓冲区限制错误。在阅读几篇博客时,我发现dbms_lob.substr()只能在sql中处理4000个字符,但在pl / sql语句中最多可以处理32k。

如果我编写一个程序并运行它,它可以正常工作。但我想在一个函数中使用它。以下是我的功能:

create or replace FUNCTION CLOBTOVARCHAR 
RETURN varchar2 is out_attribute_var varchar2(32767) ;
BEGIN
  FOR i IN (select attribute_Value  from car_course_attribute where id=1547156)
  LOOP
    out_attribute_var := dbms_lob.substr(i.attribute_Value, 32000, 1);
  END LOOP;

  RETURN out_attribute_var;

EXCEPTION
  WHEN OTHERS THEN
    raise_application_error(-20001, 'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
END CLOBTOVARCHAR;

如果数据很小,它可以正常工作,但如果数据大于4k,则会返回相同的错误。现在我有两个问题: 1)我是否正确将clob转换为varchar2,因为我想获得支点 2)我的功能是否正确?

2 个答案:

答案 0 :(得分:2)

不幸的是,Oracle中的SQL支持最多4000的varchars 您的函数在SQL查询中不起作用 您可以升级到oracle 12c,将此限制增加到32767个字符。

但是有一个简单的解决方法适用于11g,这里是一个CLOBs pivot 3列的例子:

SELECT (select val from xx
        where rowid = a_rid ) a,
       (select val from xx
        where rowid = b_rid ) b,
       (select val from xx
        where rowid = c_rid ) c
from (
  select max( case key when 'A' then rowid end ) a_rid,
         max( case key when 'B' then rowid end ) b_rid,
         max( case key when 'C' then rowid end ) c_rid
  from xx
);

这是SQLFiddle demo有3个字符串,每个字符串包含7996个字符。

此演示中的结果行非常宽,它有超过150个“水平页面” 我很惊讶SQLFiddle可以显示24K字符宽的行 此演示中的第三个查询显示了旋转柱的长度,每个柱的长度为7996个字符。

答案 1 :(得分:0)

dbms_lob.substr( clob_column, for_how_many_bytes, from_which_byte ); 

例如:

select dbms_lob.substr( x, 4000, 1 ) from T; 

将获取clob的前4000个字节。请注意,在使用SQL时,最大长度为4000.使用plsql可以获得32k:

declare 
my_var long; 
begin 
for x in ( select X from t ) 
loop 
my_var := dbms_lob.substr( x.X, 32000, 1 ); 

....

截至2016年左右,这是准确的。从Oracle Database 12c开始,我们现在支持扩展varchars2 - 现在长度为32k - 可能少于32,000,如果使用多字节字符集(每个字符2,3或4个字节),则更改字符

最初由汤姆here

回答

我只使用LiveSQL上的SQL here

将一个8k长的字符串放到varchar2中

启用了扩展varchars的12c环境的代码。

create table long_vars2 (a integer, xyz varchar2(8000), clobs clob);

create or replace procedure p( p_x in int, p_new_text in varchar2 )  
 as  
 begin  
 insert into long_vars2 (a, xyz, clobs) values ( p_x, p_new_text, p_new_text );  
 end;  
/

exec p(1, rpad('*',8000,'*') );

select dbms_lob.substr( clobs, 7000, 1 ) from long_vars2;