我存储的函数使用:Dbms_Lob.CreateTemporary(BUFFER, TRUE, Dbms_Lob.SESSION);创建临时LOB实例,其中BUFFER是一个本地CLOB变量。之后,函数将一些数据填充到BUFFER中,并返回它。
在我的例子中,Dbms_Lob.CreateTemporary的持续时间参数是Dbms_Lob.SESSION,但根据oracle文档
传递给dbms_lob.createtemporary() 的持续时间参数是一个提示。新的临时LOB的持续时间与PL/SQL中的定位器变量的持续时间相同。例如,在前面的程序块中,程序变量a具有驻留帧的持续时间。因此,在块的末尾,a的内存将在函数的末尾释放。
因此,在离开函数块后,BUFFER CLOB可能会被Oracle销毁。我可以看到,在某些情况下,当缓冲区大于32K时,我无法读取它从Java (JDBC)端以这种方式返回的值。
还有其他方法从函数返回临时CLOB实例吗?
发布于 2013-01-30 13:01:23
你在评论中说:
clob.getSubString(0, clob.length())抛出:java.sql.SQLException: Invalid argument(s) in call at oracle.sql.CLOB.getSubString(CLOB.java:236),而clob.length()返回真正长度的clob
getSubString的文档表明:
pos -要提取的子字符串的第一个字符。第一个字符位于位置1。
有了一个简单的函数来生成和返回一个CLOB,我就可以通过JDBC (ojdbc5或ojdbc6)检索它,而不存在任何问题,无论是getCLOB()还是getString()。但是,如果我尝试将使用getCLOB检索的getCLOB分配给一个String,则使用
String x = getSubString(0, clob.length());然后,我还得到了Invalid argument(s) in call错误。只是将其改为:
String x = getSubString(1, clob.length());很管用。因此,它似乎与函数中的临时分配或CLOB大小无关。我不明白为什么你对较小的CLOBs没有问题-也许你的逻辑只是没有击中这个如果他们是小的?
同时,您已经使用clob.getCharacterStream().read()来解决这个问题,所以现在可能有点不相关了。
发布于 2013-01-30 11:34:02
我创建了这个函数来返回一个clob,使用随机生成的数据,长度是200 k字符。
create function f_clob
return clob is
l_clob CLOB := EMPTY_CLOB;
l_len BINARY_INTEGER;
l_content VARCHAR2(32000);
BEGIN
dbms_lob.createtemporary(l_clob, TRUE);
dbms_lob.open(l_clob, dbms_lob.lob_readwrite);
--
for i in 1..100
loop
l_content := dbms_random.string('A', 2000);
l_len := length(l_content);
dbms_lob.writeappend(l_clob, l_len, l_content);
end loop;
dbms_lob.close(l_clob);
--
return l_clob;
end f_clob;然后我调用这个函数:
select to_char(substr(f_clob, 1, 200)) clob_chunk
from (
select 1
from dual
union
select 2
from dual)所以我总是把数据拿出来。我想知道为什么您的函数没有返回数据。
https://stackoverflow.com/questions/14586253
复制相似问题