Skip to Main Content
  • Questions
  • Converting Long Data Type to CLOB got ORA-06502

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, anil.

Asked: March 13, 2018 - 10:06 am UTC

Last updated: March 22, 2018 - 5:26 pm UTC

Version: 11g

Viewed 1000+ times

You Asked

Hi,

I am running following pl/sql code to extract image data from the table.
I am able to extract data which has length less than 32768 how ever I get ORA-06502: PL/SQL: numeric or value error: Bulk Bind: Truncated Bind when the length is more than 32768.

Please help.

table structure of IMAGE
IMAGE_FIELD    LONG
REMARKS       VARCHAR2(80)
IMAGE_LENGTH  NUMBER(5)


DECLARE
BEGIN 
  FOR R IN (SELECT  IMAGE_FIELD CLOBVALUE, REMARKS
  FROM IMAGE T WHERE IMAGE_LENGTH>32768)
  LOOP
    BEGIN
        DBMS_OUTPUT.PUT_LINE(R.REMARKS);
       EXCEPTION WHEN OTHERS THEN
        CONTINUE;
    END;      
   END LOOP;
END;

and Chris said...

Change the data type of IMAGE_FIELD a blob as soon as you can!

Longs have a huge number of restrictions. Being unable to work with values longer than 32,767 in PL/SQL is one of them.

There are some workarounds such as using dbms_sql.column_value_long to chop it up and show the bits:

https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:665224430110

But really, take the hit. Convert the LONG -> LOB in the table.

Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Problem solved

anil shrestha, March 22, 2018 - 4:24 am UTC

Hi Chris,

The database is the third party production database so changing of field to blob is out of scope.
However, I managed to solve the problem with your help and using the codes in

https://community.toadworld.com/platforms/oracle/w/wiki/3324.dbms-sql-column-value-long

Thanks again
Code for reference purpose

DECLARE
cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
fdbk PLS_INTEGER;
TYPE long_rectype IS RECORD (piece_len PLS_INTEGER, pos_in_long PLS_INTEGER, one_piece VARCHAR2(256), one_piece_len PLS_INTEGER);
rec long_rectype;
pieces DBMS_SQL.VARCHAR2S;
v_clob  CLOB:=null;
BEGIN 
  FOR R IN (SELECT IMAGE_ID , REMARKS
  FROM IMAGE T WHERE IMAGE_LENGTH>32768)
  LOOP
    BEGIN
        v_clob:=NULL;
        DBMS_SQL.PARSE (cur,'SELECT IMAGE_FIELD CLOBVALUE FROM IMAGE WHERE IMAGE_LENGTH>32768 AND ID='''||R.IMAGE_ID||'''',DBMS_SQL.NATIVE);
        DBMS_SQL.DEFINE_COLUMN_LONG (cur, 1);
        fdbk := DBMS_SQL.EXECUTE (cur);
        fdbk := DBMS_SQL.FETCH_ROWS (cur);
        IF fdbk > 0
        THEN
           rec.piece_len := 256;
           rec.pos_in_long := 0;
           LOOP
              DBMS_SQL.COLUMN_VALUE_LONG (cur,1, rec.piece_len, rec.pos_in_long, rec.one_piece, rec.one_piece_len);
              EXIT WHEN rec.one_piece_len = 0;
              pieces (NVL (pieces.LAST, 0) + 1) := rec.one_piece;
              rec.pos_in_long := rec.pos_in_long + rec.one_piece_len;
           END LOOP;
           FOR longint IN 1 ..pieces.COUNT
           LOOP
               v_clob := v_clob ||pieces(longint);
           END LOOP;
           //use v_clob as required
           DBMS_OUTPUT.PUT_LINE(R.REMARKS);
        END IF;
    END;
  END LOOP;
   DBMS_SQL.CLOSE_CURSOR (cur);        
END;

Chris Saxon
March 22, 2018 - 5:26 pm UTC

Thanks for sharing, glad you got it sorted.

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library