显示存储在 CLOB 中的大文本数据

Display Large Text Data Stored in CLOB

我正在查询我的 clob 列作为

$patch_log= oci_parse($conn_prs, "select htf.escape_sc(DBMS_LOB.substr(patch_audit, 9999)) as patch_log
from patch_files where bug_id = 12345"); 
...
echo $row['PATCH_LOG'];

我遇到错误 ORA-06502: PL/SQL: numeric or value error: character string buffer too small

因此,当我将其更改为 htf.escape_sc(DBMS_LOB.substr(patch_audit,4000)) 时,查询 运行 可以,但 returns 首先是 4000 .

该列行中的字符数在一种情况下为 49979 个字符,有时甚至更多。

我需要用php显示,怎么办?

dbms_lob.substr 返回的值为 null 的原因是因为您传递的数字大于 32767,如 the documenatation

中所述

(32767 是 pl/sql 中 varchar2 变量的最大大小,并且由于 dbms_lob.substr returns 的 CLOB 版本是一个 varchar2 值,这是可以存储的最大数据量返回并存储在 varchar2 变量中。)

很难说您应该如何传递 CLOB,因为您没有提供 htf.escape_sc 的规范 - 如果它可以接受 CLOB,那么只需将 clob 作为一个传递。否则,您将不得不将 CLOB 分块,然后以某种方式组合它们。

ETA:至于最初的错误,很可能是由于 htf.escape_sc 中的某些内容无法处理 9999 字节的字符串,或者 [= 中 varchar2 的限制25=]语句是4000字节。

Oracle+PHP Cookbook 对此进行了介绍。你不能 substr 吊球。然后在php中调用->load()获取全部内容。

发件人:http://www.oracle.com/technetwork/articles/fuecks-lobs-095315.html

$sql = "SELECT * FROM mylobs ORDER BY Id";

$stmt = oci_parse($conn, $sql);

oci_execute($stmt) or die ("Unable to execute query\n");

while ( $row = oci_fetch_assoc($stmt) ) {
    print "ID: {$row['ID']}, ";

    // Call the load() method to get the contents of the LOB
    print $row['MYLOB']->load()."\n";
}

假设您使用的是 Oracle 11.2 或更早版本

您正在传递 DBMS_LOB.SUBSTR() 一个 CLOB,这意味着 the data type of the returned value 是一个 VARCHAR2。您正在调用 SELECT 语句,这意味着您正在使用 SQL.

中的返回值

maximum size of a VARCHAR2 in SQL is 4,000 bytes. This is in marked contrast to the maximum size of a VARCHAR2 in PL/SQL,即 32,767 字节。

这就是 dbms_lob.substr(patch_audit, 4000) 有效但 dbms_lob.substr(patch_audit, 4001) 无效的原因。

这些是数据库内置的硬性限制,没有 绕过它们的方法。如果您想在 SQL 中执行此操作,则必须将 CLOB 拆分为 4,000 字节和 SELECT 数据的多个部分。这意味着遍历数据库中的 CLOB。例如,您可以执行如下操作,计算出 CLOB 和 returns N 行中的数据量,每行有 4,000 字节。

with my_clob as (
 select patch_audit 
   from patch_files 
  where bug_id = 12345 
        )
 select dbms_lob.substr(patch_audit, 4000, (level - 1) * 4000 + 1)
   from my_clob
connect by level <= ceil(dbms_lob.getlength(patch_audit) / 4000)

不要一次对多个 CLOB 执行此操作,否则您将返回大量数据并且 CONNECT BY 评估 WHERE 子句 after 层次结构已经创建子 select 是 必要的 .

,您可以只select CLOB 并在PHP 中解析它。我不知道 PHP 但 OCI-Lob::read would appear to be a good place to start. There's a few blogs out there which give you an indication; Mark Foster wrote 以下内容(为您稍作修改)

$result = oci_execute($patch_log);
    if($result !== false){
        while($row = oci_fetch_assoc($patch_log)){
            echo $row['PATCH_LOG']->read(2000);
        }
    }

假设您使用的是 Oracle 12.1 或更高版本

在 12c 中,Oracle 将 VARCHAR2(注意不是 VARCHAR)的大小增加到 32,767 bytes in SQL. In order to use this increase you have to alter the MAX_STRING_SIZE 初始化参数到 EXTENDED。这是一种单向更改,无法取消并且可能会对您的应用程序产生重大影响。 这是你要测试的东西首先

Internally the extended columns will be stored as LOBs anyway,因此无论您喜欢与否,LOB 处理都将由 Oracle 在后台完成 - 并且任何 LOB 限制可能(不知道)仍然适用。除非有真正的业务需求,否则在 PHP.

中进行一些 LOB 处理是值得的