Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, david.

Asked: July 16, 2000 - 7:46 pm UTC

Last updated: July 08, 2010 - 11:31 am UTC

Version: 8.0.4.3

Viewed 100K+ times! This question is

You Asked

I have a table with a blob field. This field contains only character data. I would like to convert the field to varchar2. Is there an easy way to do this?

The only way I can think to do this conversion is via what essentially is a byte by byte conversion.

Any ideas would be appreciated.



and Tom said...

There is a package utl_raw.

You can use

some_vc_data := UTL_RAW.CAST_TO_VARCHAR2( some_raw_data );


All that function effectively does is change the datatype marker of the raw into varchar2 and just leaves the data as is. On the way into a RAW, you can use utl_raw.cast_to_raw to conver a varchar2 into a raw type (no conversion, just a cast)

UTL_RAW may not be installed on your system. If not (there would be a grant execute to public and a public syonym if it is installed), simply:

o cd $ORACLE_HOME/rdbms/admin
o using SVRMGRL
o connect as INTERNAL or SYS (and only these 2 users, none other)
o @utlraw
o @prvrawb.plb

And thats it, it'll be there now.

Rating

  (12 ratings)

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

Comments

how to convert blob to raw

Nishant, March 14, 2002 - 12:12 pm UTC

Hi
In this reply u said everything about raw data type. but basic question is how to convert BLOB to RAW/VARCHAR2 data type. beacuse right now i am passing from powerbuilder application blob variable and when i am using this UTL_RAW.CAST_TO_VARCHAR2( some_raw_data )it requires to be raw data to convert but i have BLOB data..so how can i convert my BLOB data to RAW data.

i am bit confused in BLOB and RAW. and as powerbuilder is not supporting RAW data type i am using BLOB data type.

yr any help will be appreciated.

Thanks
Nishant


Tom Kyte
March 14, 2002 - 12:30 pm UTC

just use:

utl_raw.cast_to_varchar2( dbms_lob.substr( BLOB_LOCATOR, 32000, 1 ) );

... the biggest varchar2 variable is 32k so you will use dbms_lob.substr to get 32k chunks of it at a time.



how can i insert my blob value from sql ?

Nishant Shah, March 16, 2002 - 12:08 pm UTC

Table  : pdf_test (pdf_tk number(8), pdf_blob blob)

create or replace procedure write_pdf(tk in number,content in blob)
 as
 b_lob BLOB;
 len number;
 begin
 len:=5000;
 insert into pdf_test values(tk,empty_blob()) return pdf_blob into 
b_lob; 
DBMS_LOB.WRITE(b_lob,len,1,utl_raw.cast_to_varchar2(dbms_lob.substr(b_lob,32000,1)));
 commit;
 end;

i am passing my blob variable from powerbuilder while calling this procedure. and it fails and returns me -1 and saying procedure could  not executed. now how can i check from SQL prompt that my data has been entered in this table. i tried following ways but it fails.

SQL> execute write_pdf(1,'this is test');
BEGIN write_pdf(1,'this is test'); END;

      *
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'WRITE_PDF'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored


SQL> execute write_pdf(1,empty_blob());
BEGIN write_pdf(1,empty_blob()); END;

*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "SYS.DBMS_LOB", line 700
ORA-06512: at "SHAHPRA.WRITE_PDF", line 9
ORA-06512: at line 1

it seems to me is my procedure do not understand the supplied parameter blob variable. actually i want to save my pdf document in database. i saw examples of that. but due to security/access reasons i can't use that create directory functions of oracle. 

how can i test from SQL prompt that my blob variable has inserted ?.

any help will be appreciated ? 

Tom Kyte
March 17, 2002 - 10:29 am UTC

You won't be writing a PDF file from SQLPlus without using dbms_lob.loadfromfile.

SQPLUS is a rather rudimentary scripting environment.

SQLPlus don't have a "blob".

Your interface should be RAW, not blob using the technique above. Try:


create or replace procedure write_pdf(tk in number,content in varchar2 )
as
b_lob BLOB;
begin
insert into pdf_test values(tk,empty_blob())
return pdf_blob into b_lob;

DBMS_LOB.WRITE( b_blob, length(content), utl_raw.cast_to_raw( content ) );
end;

if you want to pass varchar2's and put them into blobs.

BTW: just advice here -- never commit in a procedure. Let the client, the caller control the transaction. committing in a procedure is a really bad idea. Sure, today your transaction is that insert and a lob write. tomorrow though, you'll want to take that procedure and some other procedure -- call them both and have that be the transaction. IMPOSSIBLE if you commit in the procedure. It is just a bad practice. Transactions should be controlled by the caller, not the callee!





how can i insert my blob value from sql ?

Nishant Shah, March 16, 2002 - 12:15 pm UTC

let me correct here that i used this way also

create or replace procedure write_pdf(tk in number,content in blob)
 as
 b_lob BLOB;
 len number;
 begin
 len:=5000;
 insert into pdf_test values(tk,empty_blob()) return pdf_blob into
b_lob;
DBMS_LOB.WRITE(b_lob,len,1,utl_raw.cast_to_varchar2(dbms_lob.substr(content,32000,1)));
 commit;
 end;
/

using CONTENT VARIABLE  as my lob loator which i m passing. but it gives me following error.

SQL> execute write_pdf(1,empty_blob());
BEGIN write_pdf(1,empty_blob()); END;

*
ERROR at line 1:
ORA-22275: invalid LOB locator specified
ORA-06512: at "SYS.DBMS_LOB", line 664
ORA-06512: at "SHAHPRA.WRITE_PDF", line 9
ORA-06512: at line 1

thanks
nishant

 

utl_raw.cast_to_varchar2

Winston, August 31, 2004 - 5:00 pm UTC

SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
PL/SQL Release 9.2.0.4.0 - Production
CORE    9.2.0.3.0       Production
TNS for Linux: Version 9.2.0.4.0 - Production
NLSRTL Version 9.2.0.4.0 - Production

SQL> select dbms_lob.getlength(blob_content ) from DB2_TRACE_FILE      where id=1318627230195021;

DBMS_LOB.GETLENGTH(BLOB_CONTENT)
--------------------------------
                        53549591

SQL> desc DB2_TRACE_FILE
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 NAME                                               VARCHAR2(4000)
 SUBJECT                                            VARCHAR2(4000)
 ID                                        NOT NULL NUMBER
 BLOB_CONTENT                                       BLOB
 MIME_TYPE                                          VARCHAR2(4000)
 DT                                                 DATE

SQL> declare
  2        l_str1      varchar2(4000);
  3        l_str2      varchar2(4000);
  4        l_leftover  varchar2(4000);
  5        l_chunksize number := 3000;
  6        l_offset    number := 1;
  7        l_linebreak varchar2(2) := chr(13)||chr(10);
  8        l_length    number;
  9        p_blob blob;
 10    begin
 11
 12        select blob_content into p_blob from DB2_TRACE_FILE      where id=1318627230195021;
 13
 14        l_length := dbms_lob.getlength(p_blob);
 15        dbms_output.put_line(l_length);
 16
 17        while l_offset < l_length loop
 18
 19           l_str1 := l_leftover ||utl_raw.cast_to_varchar2(dbms_lob.substr(p_blob, l_chunksize, l_offset));
 20           l_leftover := null;
 21           l_str2 := l_str1;
 22
 23           while l_str2 is not null loop
 24
 25            if instr(l_str2, l_linebreak) <= 0 then
 26               l_leftover := l_str2;
 27               l_str2 := null;
 28            else
 29
 30               dbms_output.put_line ( substr(l_str2, 1, instr(l_str2, l_linebreak)-1) );
 31               l_str2 := substr(l_str2, instr(l_str2, l_linebreak)+2);
 32            end if;
 33
 34           end loop;
 35
 36           l_offset := l_offset + l_chunksize;
 37
 38        end loop;
 39
 40        if l_leftover is not null then
 41        dbms_output.put_line ( l_leftover );
 42        end if;
 43
 44    end;
 45  /
53549591
declare
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at line 19


Can you please share what could go wrong? 

Tom Kyte
August 31, 2004 - 5:43 pm UTC

if l_leftover gets assigned a long line:

25 if instr(l_str2, l_linebreak) <= 0 then
26 l_leftover := l_str2;
27 l_str2 := null;
28 else

that is more than 1000 characters -- then

19 l_str1 := l_leftover
||utl_raw.cast_to_varchar2(dbms_lob.substr(p_blob, l_chunksize, l_offset));

is going to assign more than 4000 characters to l_str1.


if you are trying to save a blob to disk, i really think this trick is too cool to pass up:


</code> http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:6379798216275#19264891198142 <code>







blob to varchar

Prasad, March 04, 2005 - 10:36 am UTC

THe bolb to varchar information is very useful

Slightly confused

Matt Ball, August 06, 2005 - 5:37 am UTC

I suspect I'm missing something very basic but why do I get different results using raw_to_varchar2 when it operates on pl/sql variable and on a column in a sql statement?

Oracle9i Enterprise Edition Release 9.2.0.6.0

SQL> set serverout on
SQL> create table t1 (col1 number,
  2                   col2 blob);

Table created.
-- Sorry a bit lazy here
SQL>                  
SQL> insert into t1 (select 1,doc_contents from documents where doc_extension in ('htm','TXT','doc')
);

7 rows created.

SQL> 
SQL> select length(utl_raw.cast_to_varchar2(col2)) vc_length,dbms_lob.getlength(col2) lob_length
  2  from   t1;  

 VC_LENGTH LOB_LENGTH
---------- ----------
         6          6
      2000      19456
      2000      19456
      2000       3115
      2000    1365504
      2000      32256
      2000      47616

7 rows selected.

SQL> 
SQL> declare
  2   blob_rec t1%rowtype;
  3   v_var_blob varchar2(32767);
  4  begin
  5   for blob_rec in (select * from t1) loop
  6       v_var_blob :=  utl_raw.cast_to_varchar2(dbms_lob.substr(blob_rec.col2,32000,1));
  7       dbms_output.put_line('vc_length ='||to_char(length(v_var_blob))||'  lob_length ='||to_char
(dbms_lob.getlength(blob_rec.col2)));
  8    end loop;
  9  end;    
 10  /
vc_length =6  lob_length =6
vc_length =19456  lob_length =19456
vc_length =19456  lob_length =19456
vc_length =3115  lob_length =3115
vc_length =32000  lob_length =1365504
vc_length =32000  lob_length =32256
vc_length =32000  lob_length =47616

PL/SQL procedure successfully completed. 

Tom Kyte
August 06, 2005 - 9:34 am UTC

sql limits varchar2 to 4000 and char to 2000

raw is a "binary char" so, 2000 is the biggest it'll bind and process.

Exactly what I was looking for

Sascha, December 02, 2005 - 5:10 am UTC

I needed to see the content of a LOB as it contains XML code and the program fetching it said it could not parse the XML. Therefore it was utterly useful :-) to get help on a function that displays the char conversion of the BLOB.
Thanks Tom!

convert bloc to clob through function

sean, September 17, 2007 - 3:55 pm UTC

Hi Tom,

I have a question w/ a stored function as shown below. You can ignore accord.CONVERT (chemblob, chemclob, 'MDL Molfile'); it basically converts a BLOB in one format to CLOB in another format.



The stored function works, but I am not sure if the

DBMS_LOB.CLOSE (chemclob);

DBMS_LOB.freetemporary (chemclob);



is still effective after RETURN statement; if not, we will eventually have memory problem. Please advise me; and if so, any way to fix it?

thanks so much for your help. -- Sean



---------------- STORED FUNCTION --------------------



CREATE OR REPLACE FUNCTION b2c (chemblob IN BLOB)

RETURN CLOB

IS

chemclob CLOB;

BEGIN

/* converts the accord binary to an mdl molfile*/

DBMS_LOB.createtemporary (chemclob, TRUE);

DBMS_LOB.OPEN (chemclob, DBMS_LOB.lob_readwrite);

accord.CONVERT (chemblob, chemclob, 'MDL Molfile');

RETURN chemclob;

DBMS_LOB.CLOSE (chemclob);

DBMS_LOB.freetemporary (chemclob);

END;


Tom Kyte
September 18, 2007 - 3:47 pm UTC

those two lines of code "do not exist", they are never ever executed.


Whatever client receives this data would be responsible for closing it up after it is done (just like a cursor, an open file, any resource like that)

conver bloc to clob.

Sean, September 18, 2007 - 5:14 pm UTC

Hi Tom,

But this function is used in query. How do we close it from the client side? Thanks so much for your help.

-- Sean
Tom Kyte
September 19, 2007 - 10:28 am UTC

the client gets the lob - the client closes it after they process it. how you do that depends on the language.

you could always have the two lines of code that are never executed moved into a routine "close_that_lob" and have the client invoke that and pass the lob locator back as well.

A reader, July 16, 2009 - 11:27 am UTC


A reader, July 04, 2010 - 3:53 am UTC

Hi Tom,

You told

On the way into a RAW, you can
use utl_raw.cast_to_raw to conver a varchar2 into a raw type (no conversion,
just a cast)


but i want to convert the raw data to original data, not just the casting using utl_raw.

Is there any option for that??
Tom Kyte
July 06, 2010 - 2:43 pm UTC

what is the "original data"?

not sure what you mean.

How to Extract contents of a word doc, stored as blob in the database

A reader, July 07, 2010 - 12:42 am UTC

Hi,

I created the blob of a word doc using dbms_lob package.
And from the blob i could create the original file, using the same dbms_lob and utl_file package.

But what i want now is just to get the text/contents in that word doc. This i want to extract from the blob of that file, which is stored in the database.
Is there any way to get that??

Hope the question is clear.

Thanks in advance.

More to Explore

CLOB/BLOB/etc

Complete documentation on Securefiles and Large Objects here