我有一个要求,我必须从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)我的功能是否正确?
答案 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;