7

oracle 是否有一种方法可以根据 CLOB 字段的字节数获取子字符串?

select DBMS_LOB.SUBSTR(a.COMMENTS, 3998, 1)
FROM FOO;

我收到错误:

“ORA-06502:PL/SQL:数字或值错误:字符串缓冲区太小”

. 问题出在特殊字符上。每个新的特殊字符占用 8 个字节,因此当我将字符串限制减少到 3992 时,它就可以工作了。

DBMS_LOB.SUBSTR(a.COMMENTS, 3992, 1) works.

出于测试目的,我放置了许多特殊字符,它再次引发相同的错误。

oracle 是否有任何方法可以根据字节数而不是字符数来查找子字符串?

实际上,我们正在从表格中获取数据,并且需要在 UI 上显示,限制为 4000 个字符。因此,我们只想获取前 4000 个字符。因为,一个字符大小是 1 个字节,我们可以容纳 4000 个字节。因此,如果我们使用DBMS_LOB.CONVERTTOBLOB,我们可能无法正确显示获取的字符串。我们可以以某种方式将其转换回字符字符串吗?

4

4 回答 4

3

我成功地使用了旧的 SUBSTR 函数,它也适用于 clob 类型。在这种情况下,它是 SUBSTR(a.COMMENTS, 1, 3992)

于 2014-04-24T23:48:46.037 回答
1

这是一个老问题,但我没有找到任何解决方案,所以我会发布我的方法来找到解决这个问题的方法,以防万一有人需要处理这个......

我的任务是从 CLOB 中检索“最多”的字符。

DBMS_LOB.SUBSTR 和 SUBSTR 将获得正确的结果...

在使用 DBMS_LOB.SUBSTR 的情况下,我不断得到 ORA-12801 和 ORA-06502 使用 SUBSTR 另一个 ORA-64203..

建议说对最大 1000 做 SUBSTR,因为字符的最大字节数是 4,因此你不会得到超过 4000 个字节,不幸的是这对我来说还不够好,因为这样你可能只会收到 2000 个字节,以防万一某行不包含多字节字符...

我的解决方案是:

create or replace FUNCTION SUBSTR_MULTIBYTE_CLOB
(
  P_DATA IN CLOB 
, P_START_INDEX IN NUMBER 
) RETURN VARCHAR2 AS 
P_OUT VARCHAR2(4000 BYTE);
P_LENGTH NUMBER := 4000;
BEGIN
    FOR loop_counter IN 1..400 LOOP    
        BEGIN
            P_OUT := DBMS_LOB.SUBSTR(P_DATA,P_LENGTH-((loop_counter-1)*10),P_START_INDEX);
            RETURN P_OUT;
         EXCEPTION
            WHEN OTHERS THEN
               IF SQLCODE = -12801 OR SQLCODE = -6502 OR SQLCODE = -1401 OR SQLCODE = -1489 THEN
                  NULL; -- suppresses ORA-12801 "error signal from parallel server" or ORA-06502 exception "character string buffer too small" and some others I've got...
               ELSE
                  RAISE;
               END IF;
         END;         
    END LOOP;
END SUBSTR_MULTIBYTE_CLOB;

如果需要,您可以将循环更改为 4000 并将其减少一个字节,我决定减少 10,只是为了让它更快一点......

于 2020-02-10T10:55:11.903 回答
0

试试这个方法::

使用 Oracle 函数LENGTHB()获得此结果。有一种方法可以使用 DBMS_LOB.CONVERTTOBLOB 将CLOB转换BLOB并使用DBMS_LOB.GET_LENGTH ()。这将不返回字节数。

您可以使用此线程获得完整答案 :: https://forums.oracle.com/forums/thread.jspa?threadID=2133623

于 2012-12-11T11:41:51.890 回答
0

首先,尝试替换 Character 字符串中的所有特殊字符,然后尝试对其进行子串化以将其转换为 Character。

示例:- DBMS_LOB.SUBSTR(REGEXP_REPLACE(your_column, '[^0-9A-Za-z]', ''),3999,1)

于 2019-04-24T09:36:36.900 回答