Comparing 2 text fields SQL - Error- ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion

旧巷老猫 提交于 2021-01-29 18:04:47

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!