问题
I have seen quite of this same error with different solutions on the web, but none seem to solve what I am trying to do. I want to compare 2 text fields: PROBLEMCODE and DESCRIPTION. The text is contained in CLOB and BLOB objects some of which are ~24000 bytes (CHARs?) which throws the error:
ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion (actual: 4029, maximum: 4000)
I fully understand the root cause of this error, but I do not understand how to work around it comparing text fields. I want to check if the text PROBLEMCODE and DESCRIPTION are the same. If they are the same, use the DESCRIPTION row. Sample query and sample output:
SELECT TICKET, TEXT, TYPE
FROM TABLE
WHERE (TYPE = 'DESCRIPTION'
OR TYPE= 'PROBLEM')
Output:
TICKET TEXT TYPE
123 CLOB PROBLEM
123 CLOB DESCRIPTION
111 BLOB PROBLEM
Now, I want to say something like the following, which I think I have accomplished in the full query below, but I am not sure because I cannot test because I keep getting the buffer error.
IF TICKET PROBLEM TEXT == TICKET DESCRIPTION TEXT:
FILTER OUT PROBLEM ROW
USE DESCRIPTION ROW
So, below is my full query and filtering by single tickets, I am pretty sure, but not 100% it filters properly. My question is: How can I adjust to compensate for the buffer error? How can you compare and filter large text fields in SQL/TOAD/Oracle?
LDOWNERCOL = TYPE
SELECT
*
FROM (SELECT
TICKETID, LDTEXT, LDOWNERCOL
DENSE_RANK() OVER (PARTITION BY TICKETID ORDER BY TO_CHAR(LDTEXT)) AS Duplicated
FROM
MAXIMO.LONGDESCRIPTION INNER JOIN MAXIMO.PLUSCA ON LDKEY = TICKETUID
WHERE LDOWNERCOL IN ('DESCRIPTION', 'PROBLEMCODE')
AND (LDOWNERCOL = 'DESCRIPTION'
OR LDOWNERCOL = 'PROBLEMCODE'
OR LDOWNERCOL = 'TYPE1CODE'
OR LDOWNERCOL = 'TYPE2CODE')
)
WHERE
Duplicated = 1
When I run this, it throws the error from the TO_CHAR(LDTEXT)
, but if I add in the follow to filter out large text fields it works. How can I compensate this?
WHERE LDOWNERCOL IN ('DESCRIPTION', 'PROBLEMCODE')
AND (DBMS_LOB.GETLENGTH(LDTEXT) < 2000)
回答1:
If you compare CLOBs you need to use DBMS_LOB.COMPARE() since TO_CHAR() converts a CLOB to a varchar2. Since Varchar2 is limited in length, you cannot convert a CLOB implicit when length of CLOB exceeds maximum lenght of Varchar2. Please see my example below. First Select works with TO_CHAR() when CLOB got length of 2000 chars or less - otherwise ORA-22835 is raised. Using in second Select DBMS_LOB.COMPARE() works
connect scott/tiger
drop table t1;
drop table t2;
create table t1 (col1 number, col2 clob);
insert into t1 values
(1, 'aaaaaaaaa');
insert into t1 values
(2, 'bbbbbbbbb');
insert into t1 values
(3, 'AAAAAAAAAA');
declare
x varchar2(110) ;
c clob;
i integer;
begin
x := 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
dbms_lob.createtemporary(c, TRUE);
for i in 1..80 loop
DBMS_LOB.APPEND(c, to_clob(x));
null;
end loop;
update t1 set col2 = c where col1 = 3;
end;
/
create table t2 as select * from t1;
-- will work for rows 1 + 2 - fails for row 3 since clob length exceeds 2000
select * from t1, t2 where to_char(t1.col2) = to_char(t2.col2);
-- work since DBMS_LOB.COMPARE() is used to compare lobs
select * from t1,t2 where DBMS_LOB.COMPARE(t1.col2,t2.col2) = 0;
Output:
Connected.
SQL> SQL>
Table dropped.
SQL>
Table dropped.
SQL> SQL>
Table created.
SQL> SQL> 2
1 row created.
SQL> 2
1 row created.
SQL> 2
1 row created.
SQL> SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14
PL/SQL procedure successfully completed.
SQL> SQL>
Table created.
SQL> SQL> SQL> SQL> ERROR:
ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion (actual:
8080, maximum: 4000)
no rows selected
SQL> SQL> SQL> SQL>
COL1
----------
COL2
--------------------------------------------------------------------------------
COL1
----------
COL2
--------------------------------------------------------------------------------
1
aaaaaaaaa
1
aaaaaaaaa
COL1
----------
COL2
--------------------------------------------------------------------------------
COL1
----------
COL2
--------------------------------------------------------------------------------
2
bbbbbbbbb
2
bbbbbbbbb
COL1
----------
COL2
--------------------------------------------------------------------------------
COL1
----------
COL2
--------------------------------------------------------------------------------
3
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
3
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
来源:https://stackoverflow.com/questions/64451809/comparing-2-text-fields-sql-error-ora-22835-buffer-too-small-for-clob-to-cha