我将文本存储在数据库表中,其中许多短行包含大约70-90个字符的长字段。 (出于历史原因)。我想将这些字段(行)附加到APEX(CKEditor)的CLOB中,并且在许多情况下确实超过了32k。 我已经尝试了很多方法,但是似乎有些局限。只要文本小于32k,我的代码就可以正常工作!我的计划是将其保存在新表中,并使用Clob代替。我有APEX 5.01。 超过32k时,出现“ ORA-06502:PL / SQL:数字或值错误”。
declare
l_clob CLOB;
l_seq number;
cursor textrader_cur is
SELECT F1NR,FHTTYP,RADNR,FHTEXT,DATUM,UPPTAGEN,NUSER FROM DATATXT WHERE DATATXT.F1NR = :P10_F1NR ORDER BY F1NR,FHTTYP,RADNR;
TYPE datatext_typ IS TABLE OF DATATXT%ROWTYPE INDEX BY PLS_INTEGER;
l_datatext datatext_typ;
begin
l_clob := empty_clob();
DBMS_LOB.CREATETEMPORARY(l_clob,true);
apex_collection.create_or_truncate_collection(p_collection_name => 'TEXT');
select count(1) into x from DATATXT@HUMANAUTV WHERE DATATXT.F1NR = :P10_F1NR;
if x > 0 then
open textrader_cur;
loop
fetch textrader_cur bulk collect into l_datatext LIMIT 200;
for indx in 1..l_datatext.COUNT loop
y := length(l_datatext(indx).fhtext);
dbms_lob.writeappend (l_clob,y,l_datatext(indx).fhtext);
--l_clob := l_clob || l_datatext(indx).fhtext; -- This causes same error
end loop;
EXIT WHEN l_datatext.COUNT = 0;
end loop;
close textrader_cur;
l_seq := apex_collection.add_member(p_collection_name => 'TEXT',
p_d001 => sysdate,
p_d002 => sysdate,
p_n001 => dbms_lob.getlength(l_clob),
p_clob001 => l_clob);
-- :P10_WP := l_clob;
SELECT clob001 into :P10_WP FROM APEX_COLLECTIONS WHERE SEQ_ID = l_seq AND COLLECTION_NAME='TEXT';
end if;
end;
答案 0 :(得分:1)
PL / SQL提供了一个dbms_lob包来操纵此数据类型。我在另一种技术(zope / python)中解决类似问题的方式是创建一个框架: 要从db读取,它以多行返回数据 要写入db,它将以多象素调用的形式发送数据,服务器最终将其合并。
答案 1 :(得分:0)
问题是代码的最后一行。会话状态变量(例如P10_WP
)均为VARCHAR2
,并且限制为32767个字符。您可以在调用它们的APEX函数中看到(example)。因此,您不能为PL / SQL页面项分配超过32k个字符。
但是显然,您可以在HTML表单项中放置超过32k个字符!因此,这是一个尴尬的解决方法-您必须在不使用APEX页面项目的情况下将Clob数据传入和传出HTML表单项目。通常,这是通过将Clob写入Collection,然后使用AJAX调用Application Process来检索它来完成的,因为JavaScript的字符限制没有问题。
您似乎已经TEXT
集合自己一个人了,但是您仍然必须编写自己的按需应用程序流程,以便可以将集合加载到JavaScript中,并且从那里将其放在HTML表单项中。如果您将内置的apex.ajax.clob
功能与CLOB_CONTENT
集合一起使用,将会更容易。
我浏览了一些有关此的文章,以及this one is pretty well written and straightforward。
简短的版本是将代码中的集合名称更改为CLOB_CONTENT
,然后将此JavaScript函数放在页面上并调用它。
function clob_get(){
var clob_ob = new apex.ajax.clob(
function(){
var rs = p.readyState
if(rs == 1||rs == 2||rs == 3){
$x_Show('AjaxLoading');
}else if(rs == 4){
$s('P10_WP',p.responseText);
$x_Hide('AjaxLoading');
}else{return false;}
}
);
clob_ob._get();
}
答案 2 :(得分:0)
APEX中的PL / SQL限制为32k,pl / sql将Clobs视为varchar,仅此而已。我的问题无法在APEX内解决