3

我有一个要求,我必须从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)我是否正确地将clobvarchar2 转换为我想要获得枢轴 2)我的函数是否正确?

4

2 回答 2

2

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

但是有一个适用于 11g 的简单解决方法,这里是 3 列的 CLOB 透视示例:

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
);

这是带有 3 个字符串的SQLFiddle 演示,每个字符串包含 7996 个字符。

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

于 2013-08-19T17:31:32.857 回答
1
dbms_lob.substr( clob_column, for_how_many_bytes, from_which_byte ); 

for example:

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

will get me the first 4000 bytes of the clob. Note that when using SQL as I did, the max length is 4000. You can get 32k using plsql:

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

....

This was accurate as of 2016 or so. As of Oracle Database 12c, we now support extended varchars2's - up to a length of now 32k - which may be fewer than 32,000 and change characters if using Multi-Byte character set (2,3,or 4 bytes per character)

Originally answered by Tom here

I have a working scenario for an 8k long string into a varchar2 using just SQL on LiveSQL here

The code for a 12c environment with extended varchars enabled.

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;
于 2018-03-17T13:22:45.537 回答