当我使用包含 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 行
发生了什么事以及如何解决这个问题?
这是一个编码问题。当记录包含“损坏”字符时,
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;
/