Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using DBMS_LOB.SUBSTR on a BLOB results in ORA-06502

When I try to run the dbms_lob.substr function on a BLOB field, I get the following error:

ORA-06502: PL/SQL: numeric or value error: raw variable length too long

ORA-06512: at line 1

My query:

select dbms_lob.substr(my_report, 10000, 1) 
from my_table where my_table.report_id = :myid

According to the dbms_lob.substr documentation, I should be able to use a value in the 2nd parameter up to 32767, and the size of the report is over 200,000 bytes, so it is within the range.

After playing with the number, I have found that the make value that I can use in the amount parameter (2nd parameter) to the substr function is 2000.

Does anyone know why?

like image 506
Zach Green Avatar asked Oct 28 '11 17:10

Zach Green


People also ask

What does DBMS_LOB Substr do?

When calling DBMS_LOB . SUBSTR from the client (for example, in a BEGIN / END block from within SQL*Plus), the returned buffer contains data in the client's character set. Oracle converts the LOB value from the server's character set to the client's character set before it returns the buffer to the user.

Can you Substr a CLOB?

SUBSTR works with CLOBs in 10g and 11g.

What does DBMS_LOB Createtemporary do?

n createtemporary: The procedure createtemporary creates a temporary CLOB or BLOB and its corresponding index in the user default temporary tablespace. n instr: Used to return the matching position of the nth occurrence of the pattern in the LOB. n getlength: Used to get the length of specified LOB.

What can you do with the DBMS_LOB package?

The DBMS_LOB package provides subprograms to operate on BLOBs, CLOBs, and NCLOBs. You can use DBMS_LOB to access and manipulate specific parts of LOBs or complete LOBs. You can also refer to "Large objects (LOBs)" in Oracle TimesTen In-Memory Database PL/SQL Developer's Guide.


2 Answers

The function is returning the result as the RAW datatype, and the RAW datatype has a maximum size of 2000 bytes.

References:

http://download.oracle.com/docs/cd/B10501_01/server.920/a96540/sql_elements2a.htm#SQLRF0021

http://dbaforums.org/oracle/index.php?showtopic=8445

like image 157
Zach Green Avatar answered Oct 19 '22 20:10

Zach Green


The length limitation of 2000 octets applies to the sql engine only. In Pl/sql you may exploit the whole range of up to a length of 32767 (2^15-1).

As of 12c, the length limitation of 2000 has been lifted.

However, prior to 12c there is a length limitation in the sqlplus client that does not allow for column sizes above 4000 ( The value for 11g2 ).

The following code works for 11g2 and later

var myid number;
exec :myid := 1234; -- whatever

DECLARE
    l_r   RAW(32767);
BEGIN
    select dbms_lob.substr ( my_report, 2000, 1 ) head
      into l_r
      from my_table
     where my_table.report_id = :myid  
       ;

  l_r := UTL_RAW.COPIES ( l_r, 10 );
  dbms_output.put_line ( 'id ' || :myid || ', len(l_r) = ' || utl_raw.length(l_r));
END;
/
show errors 

... while this version requires 12c:

var myid number;
exec :myid := 1234; -- whatever

DECLARE
    l_r   RAW(32767);
BEGIN
    select dbms_lob.substr ( my_report, 32767, 1 ) head
      into l_r
      from my_table
     where my_table.report_id = :myid  
       ;

  dbms_output.put_line ( 'id ' || :myid || ', len(l_r) = ' || utl_raw.length(l_r));
END;
/
show errors 
like image 27
collapsar Avatar answered Oct 19 '22 21:10

collapsar