dqhbuwrwq692118284 2015-02-11 15:35
浏览 559
已采纳

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

I am querying my clob column as

$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'];

I am getting the error ORA-06502: PL/SQL: numeric or value error: character string buffer too small

So when I am changing it to htf.escape_sc(DBMS_LOB.substr(patch_audit,4000)) the query is running fine but returns first 4000.

The number of characters in that column row is 49979 characters in one case and sometimes even more.

I need to display it with php, how can I do it?

  • 写回答

3条回答 默认 最新

  • dongqian5569 2015-02-14 13:15
    关注

    Assuming you're using Oracle 11.2 or earlier

    You're passing DBMS_LOB.SUBSTR() a CLOB, which means the data type of the returned value is a VARCHAR2. You're calling a SELECT statement, which means you're using the returned value in SQL.

    The 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, which is 32,767 bytes.

    This is why dbms_lob.substr(patch_audit, 4000) works but dbms_lob.substr(patch_audit, 4001) will not.

    These are hard limits built into the database and there's no way around them. If you want to do this in SQL you have to split up your CLOB on 4,000 byte and SELECT multiple parts of the data. This means iterating through the CLOB in the database. For instance you could do something like the following, which works out the amount of data in the CLOB and returns N rows, each with 4,000 bytes.

    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)
    

    Don't do this on more than one CLOB at a time otherwise you'll be returning huge amounts of data and CONNECT BY evaluates the WHERE clause after the hierarchy has been created so a sub-select is necessary.

    Or, you could just select the CLOB and parse it in PHP. I don't know any PHP but 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 the following (modified slightly for you)

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

    Assuming you're using Oracle 12.1 or later

    In 12c Oracle increased the size of the VARCHAR2 (note not VARCHAR) to 32,767 bytes in SQL. In order to use this increase you have to alter the MAX_STRING_SIZE initialization parameter to EXTENDED. This is a one way change, which can't be backed out and could have large impacts on your application. It's something you want to test first.

    Internally the extended columns will be stored as LOBs anyway, so LOB processing will be done in the background by Oracle whether you like it or not - and any LOB restrictions may (don't know) still apply. Unless there's a genuine business need it's worth just doing some LOB processing in PHP.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?
  • ¥100 求三轴之间相互配合画圆以及直线的算法
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 自己瞎改改,结果现在又运行不了了