ORA-22921:输入缓冲区的长度小于请求的数量

问题描述 投票:0回答:1

当我使用包含 BLOB 列的表时:

SELECT id FROM table WHERE blob_column LIKE '%something%';

...我收到以下错误:

ORA-22835:缓冲区太小,无法进行 CLOB 到 CHAR 或 BLOB 到 RAW 的转换(实际:16713,最大:4000)

这个SO问题的答案解决了转换函数的问题,这似乎对我有帮助:

CREATE OR REPLACE FUNCTION VC2CLOB_FROM_BLOB(B BLOB)
RETURN CLOB IS
    c CLOB;
    n NUMBER;
BEGIN
    IF (b IS NULL) THEN 
        RETURN NULL;
    END IF;
    IF (LENGTH(b) = 0) THEN
        RETURN EMPTY_CLOB();
    END IF;
    DBMS_LOB.CREATETEMPORARY(c, TRUE);
    n := 1;
    WHILE (n + 32767 <= LENGTH(b)) LOOP
        DBMS_LOB.WRITEAPPEND(c, 32767, UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(b, 32767, n)));
        n := n + 32767;
    END LOOP;
    DBMS_LOB.WRITEAPPEND(c, LENGTH(b) - n + 1, UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(b, LENGTH(b) - n + 1, n)));
    RETURN c;
END;
/

但是,尝试一下:

SELECT id FROM table WHERE VC2CLOB_FROM_BLOB(blob_column) LIKE '%something%';

...我仍然遇到错误:

ORA-22921: 输入缓冲区的长度小于请求的数量 ORA-06512: 在“SYS.DBMS_LOB”,第 1163 行 ORA-06512: 在 “DATABASE.VC2CLOB_FROM_BLOB”,第 18 行

发生了什么事以及如何解决这个问题?

oracle blob varchar2
1个回答
0
投票

这是一个编码问题。当记录包含“损坏”字符时,

UTL_RAW.CAST_TO_VARCHAR2
的返回值比为 CLOB 缓冲区大小计算的值要短,从而导致上述错误。

虽然它不能正确解决底层编码问题,但我通过修补该函数来避免出错:

CREATE OR REPLACE FUNCTION VC2CLOB_FROM_BLOB(B BLOB)
RETURN CLOB IS
    c CLOB;
    l NUMBER;
    n NUMBER;
    tmp VARCHAR2(32767);
BEGIN
    IF (b IS NULL) THEN 
        RETURN NULL;
    END IF;
    l := DBMS_LOB.GETLENGTH(b);
    IF (l = 0) THEN
        RETURN EMPTY_CLOB();
    END IF;
    DBMS_LOB.CREATETEMPORARY(c, TRUE);
    n := 1;
    WHILE (n + 32767 <= l) LOOP
        DBMS_LOB.WRITEAPPEND(c, 32767, UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(b, 32767, n)));
        n := n + 32767;
    END LOOP;
    tmp := UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(b, l - n + 1, n));
    DBMS_LOB.WRITEAPPEND(c, LEAST(l - n + 1, LENGTH(tmp)), tmp);
    RETURN c;
END;
/
© www.soinside.com 2019 - 2024. All rights reserved.