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
,我们可能无法正确显示所提取的字符串。我们能否以某种方式将它转换回charater string?
答案 0 :(得分:2)
我成功使用了旧的SUBSTR函数,它也适用于clob类型。在这种情况下,它的SUBSTR(a.COMMENTS,1,3992)
答案 1 :(得分:0)
试试这个方法::
使用Oracle函数 LENGTHB()来获得此结果。有一种方法可以使用 DBMS_LOB.CONVERTTOBLOB 将 CLOB 转换为 BLOB 并使用 DBMS_LOB.GET_LENGTH()。这将返回no字节。
您可以使用此主题获得完整答案:: 的 https://forums.oracle.com/forums/thread.jspa?threadID=2133623 强>
答案 2 :(得分:0)
首先,尝试替换字符串中的所有特殊字符,然后尝试对其进行子字符串转换为字符。
示例:-DBMS_LOB.SUBSTR(REGEXP_REPLACE(your_column,'[^ 0-9A-Za-z]',''),3999,1)
答案 3 :(得分:0)
这是一个老问题,但是我没有找到任何解决方案,所以我将发布我的方法来找到该问题的解决方案,以防万一有人需要处理此问题...
我的任务是从CLOB中检索“最多”字符。
DBMS_LOB.SUBSTR或SUBSTR都将获得正确的结果...
在使用DBMS_LOB.SUBSTR的情况下,我不断将ORA-12801与ORA-06502一起使用 使用SUBSTR的另一个ORA-64203 ..
建议说SUBSTR最多为1000,因为字符的最大字节数为4,因此您得到的字节数不会超过4000,不幸的是,这对我来说不够好,因为这样您可能只会收到2000字节,以防某些行不包含多字节字符...
我的解决方案不应该用于重复查询(而是用于将数据提取和加载/存储到VARCHAR2列中),
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,并将其减少1个字节,我决定将其减少10个字节,只是为了使其速度更快一点...