4

我的存储函数使用以下方法创建临时 LOB 实例:Dbms_Lob.CreateTemporary(BUFFER, TRUE, Dbms_Lob.SESSION);where BUFFERis a local CLOBvariable。之后,该函数会填充BUFFER一些数据并将其返回。

Dbms_Lob.CreateTemporary在我的情况下,持续时间参数是Dbms_Lob.SESSION,但根据oracle 文档

传递给 dbms_lob.createtemporary()的持续时间参数是一个提示。新临时 LOB 的持续时间与 PL/SQL 中定位器变量的持续时间相同。例如,在前面的程序块中,程序变量a具有驻留帧的持续时间。因此,在块结束时, a 的内存将在函数结束时被释放。

所以BUFFER CLOB离开功能块后可能会被Oracle破坏。我可以看到,在某些情况下,当 BUFFER 超过 32K 时,我无法读取从 Java(JDBC)端以这种方式返回的值。

有没有其他方法可以从函数返回临时 CLOB 实例?

4

2 回答 2

4

你在评论中说:

clob.getSubString(0, clob.length())throws: java.sql.SQLException: Invalid argument(s) in call at oracle.sql.CLOB.getSubString(CLOB.java:236)whileclob.length() 返回我的 clob 的实际长度

的文件getSubString指出:

pos - 要提取的子字符串的第一个字符。第一个字符位于位置 1。

使用一个简单的函数来生成和返回一个 CLOB,我可以通过 JDBC ( ojdbc5or ojdbc6) 毫无问题地检索它,无论是使用getCLOB()or getString()。但是,如果我尝试将Oracle.sql.CLOB检索到的 with分配getCLOBStringusing

String x = getSubString(0, clob.length());

然后我也得到了Invalid argument(s) in call错误。只需将其更改为:

String x = getSubString(1, clob.length());

作品。所以它似乎与函数中的临时分配或CLOB大小无关。我不明白为什么你对较小的 CLOB 没有问题 - 如果它们很小,也许你的逻辑没有达到这个目标?

与此同时,您已经解决了这个问题clob.getCharacterStream().read(),所以现在这可能有点无关紧要。

于 2013-01-30T13:01:23.047 回答
3

我创建了一个函数来返回一个带有随机生成数据的 clob,长度为 200k 个字符。

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)

结果我总是把数据拿出来。我想知道为什么你的函数没有返回数据。

于 2013-01-30T11:34:02.357 回答