Skip to Main Content

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Lynn.

Asked: August 21, 2000 - 5:51 am UTC

Last updated: May 23, 2022 - 3:46 am UTC

Version: Version 8.1.5

Viewed 10K+ times! This question is

You Asked

I have 2 tables with 2 columns each; first column is VARCHAR2 & the second is LONG RAW - to store images - for both tables.

I am trying to create 2 tables (for trial purposes) based on these tables using the following statement:-
CREATE TABLE <name>
AS
SELECT * FROM emp;
It gives me an error saying 'Illegal use of Long datatype'.

I tried inserting into the tables after creating them, but that also gives me the same error.

Could you suggest how to create the tables and also how to merge records in them?

Thanks & regards
Lynn


and Tom said...

In Oracle8i, releases 8.0 and up, you should not be using LONG RAW. Both LONG and LONG RAW are only provided for backwards compatibility -- they are deprecated datatypes.

You should be using blob -- then its as easy as above (create table as select). LONGS and LONG RAWS come with many many limits (no use in WHERE clause, no insert into select LONG, no create table as SELECT, no chance of manipulation in PLSQL -- only in 3gls, no replication, etc, etc, etc). BLOBS and CLOBS do not suffer from these limits.

To copy a long raw into another table without writing a program in C or VB or Java or some other 3gl you can:

o export the table (emp in your example)
o rename the table emp to <name> using the RENAME command
o import the export you just created

To merge them (say you wanted to take the table EMP and the table NAME and have EMP have all of the records at the end) you would:

o export that table NAME
o drop table NAME
o rename EMP to NAME
o import with ignore=y to add the rows to NAME
o rename NAME to EMP

remember to set BUFFER really large for the export and import to avoid issues with exp and imp and large columns.

With LONGS (not LONG RAWS) you can use the sqlplus copy command as well, see
</code> http://asktom.oracle.com/Misc/MoveLongs.html <code>
for details.




Rating

  (27 ratings)

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

Comments

Long Raw Datatypes

Lynn, July 10, 2001 - 5:44 am UTC


But BLOBs are _not_ compatible with Forms5 & Long Raw IS!!

Suzanne Michelle, Rod Patwell, November 20, 2001 - 12:38 pm UTC

The title says it all. We have exactly same scenario, wanted to copy from one to another, but couldn't. Tried exporting, no good. We are still using Forms5, because we are just not ready to go to Forms 6i. And, to our knowledge, Forms5 doesn't work with LOBs. Enlighten if this is not true, thanks!

Tom Kyte
November 20, 2001 - 1:04 pm UTC

tell me why export didn't work (it does, used it many times myself)?

Make sure to set buffer= to a large value for the EXP but it sure does work...

You'll have to supply more information.

We have to do it!

Platinum, December 13, 2001 - 3:27 am UTC

Is there any other method where we can replicate the long raw datatype?
I need to replicate the long raw data for audit purpose, surely a mass copy of the table will not serve the purpose.
Please advise.
Thanks

Tom Kyte
December 13, 2001 - 8:55 am UTC

don't use long raw. period. its a very simple answer. use a BLOB.


You can always implement a flag delete as well -- don't UPDATE the row, end_date the old row and insert a new row. That's a more efficient "audit" anyway, rather then copy the entire old row AND update the old row, just update an end_date column and insert a new row.

Thanks!

Bill Coulam, June 19, 2002 - 5:41 pm UTC

Very helpful. I was starting down the usual road of vainly searching through the Oracle docs, when it occurred to me to check your site FIRST this time. You probably saved me hours of fruitless reading, thanks!

Changing Tablespaces

A reader, October 01, 2002 - 11:22 am UTC

Tom....
Great Site...
We have some existing tables that have LONG and LONG RAW columns in them..
We are shifting from Dictionary Managed to Locally Managed tablespaces.
Alter table move tablespace results into an error..
ORA-00997: illegal use of LONG datatype
Can Export/Import accomplish that...
If yes how?

Database: 8.1.7.3.4
OS: UNIX

Thanks..

Tom Kyte
October 02, 2002 - 9:32 am UTC

sqlplus copy can work with longs if you like

export import will do both longs and long raws.

Make sure to have a backup! before doing the export/import trick as you typically DROP the table after the export, before the import. If something were to go wrong with IMP, you would like to have a backup of course!

this solved my problem for me.

Laurie, October 20, 2004 - 3:10 pm UTC

thank you!!

How to get "long raw" out of sqlplus

Randy, February 18, 2005 - 2:22 pm UTC

Is there a way to see "long raw" data in sqlplus?
All I see is the first nibble.
A hex dump would be great.
Even knowing the length would help.

I take to heart not to use them, but the customer's application does.

I tried
column data format a20
column data format 99999999
SET LONGCHUNKSIZE 20
SET LONG 20
SET NUMWIDTH 20

"length(data)" also does not work...
Thanks, -r

Tom Kyte
February 18, 2005 - 3:06 pm UTC

is the long raw 32k or less? if so, i can help you, if not, no -- you'd have to use a blob.

Copying table data with Long Raw column

Anant, June 16, 2005 - 8:49 pm UTC

Tom: As you mentioned I tried to Export the table with long raw column with a buffer=4096000. Export terminated without warnings but it did not export data. The data is less than 32K.
This is a vendor DB and I do not have the choice of changing the data type of the column. However, I have to sync copy of the table. As you already mentioned, MV/replication do not work.
Can you suggest suitable buffer size?
Thanks

Tom Kyte
June 16, 2005 - 10:21 pm UTC

should have worked, please utilize support as if it did not work, it would be "buggy behavior"

(but you do not give a full testcase so I don't really know what you did...)

Inserting Long Raws

Caleb, August 15, 2005 - 4:57 pm UTC

I have been blessed with an application that makes extensive use of Long Raws.
On occasion I have needed to do an insert or update from one table to another an
populate the the table or rows with long raw data.

The following pseudo PLSQL code can be used to update on table with another
tables long raw data:

DECLARE
CURSOR MyCursor IS SELECT Field1, Field2, RawField FROM Table1;
vField1 integer;
vField2 varchar2(50);

vRawField long raw;
iCount integer;
BEGIN
iCount := 0;

OPEN MyCursor;

LOOP
FETCH MyCursor INTO vField1, vField2, vRawField;
EXIT WHEN MyCursor%NOTFOUND;
iCount := iCount + 1;
INSERT INTO Table2 (T2Field1, T2Field2, T2RawField)
VALUES (vField1, vField2, vRawField);

--Commit every 10 rows
IF iCount = 10 THEN
iCount := 0;
COMMIT;
END IF;

END LOOP;
COMMIT;
CLOSE MyCursor;
END;

I've also created views that decode the long raw fields (Calling a package); If
it would be useful, I could also post this code as well.

-Caleb
Sleep is just a symptom of caffeine deprivation

Tom Kyte
August 15, 2005 - 10:41 pm UTC

*as long as the long raw is 32k or LESS*

Else this will not work.

A reader, October 27, 2005 - 4:33 pm UTC

Is there any limit of long raw data size to work correctly for EXP/IMP tolls?

Tom Kyte
October 28, 2005 - 1:43 am UTC

EXP/IMP tolls?

just see the original answer - look at buffer.

reader

A reader, October 28, 2005 - 3:43 pm UTC

I would like to know if long datatype deprecated in 10g

Tom Kyte
October 29, 2005 - 10:45 am UTC

it is sort of deprecated in all releases since clobs and blobs came out if you ask me, I would not personally even consider using it for anything new.


It is however still fully supported in 10g.

copy in pl/sql

Gabriel, November 09, 2005 - 4:37 pm UTC

Hello Tom,

Would copy work in PL/SQL within an execute immediate?

Thank you,

Tom Kyte
November 11, 2005 - 10:28 am UTC

no, it is a "subroutine coded in the sqlplus executable itself"

BLOB - LONG RAW

Paul, December 21, 2005 - 11:38 am UTC

I have a table that, when I "select *", it says that my field in question contains "(BLOB)" but when I do a describe, it says the field is a "LONG RAW". Why would it say BLOB when I "select", when it is really a LONG RAW?

Tom Kyte
December 21, 2005 - 7:45 pm UTC

what "api" says this to you?

Trying to use Caleb's Method above

Jon, February 16, 2006 - 11:24 am UTC

Hi,

I am trying to use the method that Caleb mentions above for copying a table containing a long raw field to another table using a cursor, fetch, insert, etc.

The only difference I can see besides field and table names is that I have a total of 7 fields, number, varchar2 and the one long raw as the 6th field.

When I run the statement I get...

DECLARE
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at line 17

Removing the long raw field from the DECLARE gets past this error, but defeats the purpose.

Could this be indicative of the long raw data being greater than 32k? Is there an easy way to verify the length?

Thanks,

Jon

Tom Kyte
February 17, 2006 - 1:03 pm UTC

for anything >32k that is LONG RAW, you cannot use plsql.  This approach might work (to get the long raw length).  You can call this from sql or from plsql and would call it before reading out the long raw (to see that you CAN in fact read it out).

But you can use the same technique to read and write a long raw in java as well if you *really* need to copy it.


ops$tkyte@ORA9IR2> create or replace and compile java source named "long_raw" as
  2  import java.io.*;
  3  import java.lang.*;
  4  import java.sql.*;
  5  import java.util.*;
  6  import oracle.jdbc.driver.*;
  7  import java.math.*;
  8
  9  public class long_raw
 10  {
 11      public static java.math.BigDecimal getlength(java.lang.String p_query, oracle.sql.ARRAY p_binds) throws Exception
 12      {
 13                  int length;
 14                  int tot_length = 0;
 15                  Connection conn = DriverManager.getConnection("jdbc:default:connection:");
 16                  PreparedStatement pstmt = conn.prepareStatement(p_query);
 17                  String[] binds = (String[])p_binds.getArray();
 18                  for( int i = 0; i < p_binds.length(); i++ )
 19                  {
 20                          pstmt.setString( i+1, binds[i] );
 21                  }
 22          ResultSet rset = pstmt.executeQuery();
 23
 24                  if ( rset.next() )
 25          {
 26              InputStream is = rset.getBinaryStream(1);
 27                  byte buffer[] = new byte[1024];
 28              while ((length = is.read (buffer,0,1024)) != -1)
 29                                  tot_length += length;
 30              is.close();
 31          }
 32          rset.close();
 33                  pstmt.close();
 34                  return new java.math.BigDecimal( tot_length );
 35      }
 36  }
 37  /
 
Java created.
 
ops$tkyte@ORA9IR2> show error
No errors.
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> create or replace function long_raw_length( p_query in varchar2, p_binds in strArray ) return number
  2  as language java
  3  name 'long_raw.getlength( java.lang.String, oracle.sql.ARRAY ) return java.math.BigDecimal';
  4  /
 
Function created.
 
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> drop table t;
 
Table dropped.
 
ops$tkyte@ORA9IR2> create table t ( x int, y int, z long raw );
 
Table created.
 
ops$tkyte@ORA9IR2> insert into t values ( 1, 2, '0a0a0a0a' );
 
1 row created.
 
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> select x, y, long_raw_length('select z from t where x = ? and y = ?', strArray(x,y) ) lrl
  2    from t;
 
         X          Y        LRL
---------- ---------- ----------
         1          2          4
 
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> select max( long_raw_length('select piece from sys.idl_ub1$ where obj#=to_number(?) and part=to_number(?) and
  2  version=to_number(?) and piece# = to_number(?)', strArray(obj#,part,version,piece#) ) ) from sys.idl_ub1$;
 
 
MAX(LONG_RAW_LENGTH('SELECTPIECEFROMSYS.IDL_UB1$WHEREOBJ#=TO_NUMBER(?)ANDPART=T
-------------------------------------------------------------------------------
                                                                          32767




That routine is not fully tested, just sort of cobbled it together.  Could be optimized I am sure (by a real java programmer :)  Just don't let the java programmer take out the bind variable bit!

 

is LONG RAW cached as other normal data block?

Jianhui, May 12, 2006 - 2:43 pm UTC

Hi Tom,
I have two questions. First, I am wondering whether blocks holding LONG RAW are cached as other normal data blocks or not, or is it direct physical read bypass SGA?

Secondly, we have a legacy applicatin uses LONG RAW to store tons of images and very much read intensive by PK index scan on those images(executions per second is very high yet each execution is based PK index), by increasing buffer cashe 30+%, hit ratio only gets 0.5 point increase(92.5% to 93%). Since this system has many free memory, how do we take advantage of the free memory to improve either performance or capacity. It seems adding it to buffer cache does not give us good return.

Sincerely,

Tom Kyte
May 12, 2006 - 9:33 pm UTC

long raws are just column data on blocks - normal caching.




you do understand that all IO must be physical IO at least once? Meaning - an infinitely sized buffer cache will still do physical IO until the entire thing is there...

use statspack, buffer cache adivisor - it is pretty good at telling you what can be accomplished.

How about RAW

Shekhar Pandit, February 06, 2007 - 4:17 pm UTC

Hi Tom

Thanks for all the answers.

But everywhere (even in documentation) it is explained that use BLOB instead of LONG RAW. What about RAW datatype? If I know i need to store 128bytes of Binary data can I use RAW(128) ?

Thanks
-Shekhar
Tom Kyte
February 06, 2007 - 4:38 pm UTC

raw is fine

An answer, please

Bruno Paquet, August 27, 2008 - 8:59 pm UTC

Your java code answer half of the original question, since you have java co-workers, can you give a real example of a copy from and to a table with long raw. I repeat, your exemple is like very usefull, but the true complexity here is to read from and write to a long raw.

Thank you M. Kyte.
Tom Kyte
August 29, 2008 - 1:33 pm UTC



You'll really want to do this as an exercise for yourself - truly. You are planning on sticking this into a production system right? You "own" the code, you have to maintain it - you'll truly want to be able to write it.

And actually, I don't have any "java coworkers", I am purely a database guy :)


and I answered the question 100% fully the first time around. export/import. That'd be my suggestion (no code, always go for NO CODE) - in 10g, you can use the data pump even..

DBMS_CRYPTO

Hari Krishna, October 02, 2010 - 12:01 pm UTC

Dear Tom,

I got below error when i am executing the following .
How i resolve it please give me solution.

SQL> declare
  2         l_key     varchar2(2000) := '1234567890123456';
  3         l_in_val  varchar2(2000) := 'ConfidentialData';
  4         l_mod     number := dbms_crypto.ENCRYPT_AES128
  5                             + dbms_crypto.CHAIN_CBC
  6                             + dbms_crypto.PAD_PKCS5;
  7         l_enc     raw (2000);
  8      begin
  9        l_enc := dbms_crypto.encrypt
 10       (
 11           UTL_I18N.STRING_TO_RAW (l_in_val, 'AL32UTF8'),
 12           l_mod,
 13            UTL_I18N.STRING_TO_RAW (l_key, 'AL32UTF8')
 14     );
 15       dbms_output.put_line ('Encrypted='||l_enc);
 16     end;
 17     /
       l_mod     number := dbms_crypto.ENCRYPT_AES128
                           *
ERROR at line 4:
ORA-06550: line 4, column 28:
PLS-00201: identifier 'DBMS_CRYPTO' must be declared
ORA-06550: line 4, column 18:
PL/SQL: Item ignored
ORA-06550: line 9, column 16:
PLS-00201: identifier 'DBMS_CRYPTO' must be declared
ORA-06550: line 9, column 7:
PL/SQL: Statement ignored

Tom Kyte
October 04, 2010 - 2:01 am UTC

get your DBA to grant you access to the package.

getting error for long_raw_length

Sush, October 07, 2010 - 9:00 am UTC

create or replace and compile java source named "long_raw"
java created 

but for long_raw_length i got the error

Warning: Function created with compilation errors.

SQL> show error
Errors for FUNCTION LONG_RAW_LENGTH:

LINE/COL ERROR
-------- -----------------------------------------------------------------
0/0      PL/SQL: Compilation unit analysis terminated
1/59     PLS-00201: identifier 'STRARRAY' must be declared


-----------------------------------------------------------
I came across your Long raw datatypes as i am looking for solution to my below table having some pdf and word docs

SQL> desc quot_ole
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 QUOT_NUMBER                                        VARCHAR2(30)
 QUOT_OBJECT                                        LONG RAW
 QUOT_HEAD                                          VARCHAR2(250)

 SQL> declare
  2  a varchar(32767);
  3  b long raw;
  4  cursor c1 is
  5  SELECT quot_object
  6  FROM quot_ole;
  7  begin
  8  open c1;
  9  loop
 10  fetch c1 into b ;
 11  exit when c1%notfound;
 12  a:=utl_raw.cast_to_varchar2(b);
 13  dbms_output.put_line(a);
 14  end loop;
 15  end;
 16  /
declare
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at line 10

Tom Kyte
October 11, 2010 - 10:19 am UTC

Just use sys.odciVarchar2List nowadays - strarray was just a table of varchar2's

ops$tkyte%ORA11GR2> create or replace function long_raw_length( p_query in varchar2, p_binds in sys.odciVarchar2List ) return number
  2  as language java
  3  name 'long_raw.getlength( java.lang.String, oracle.sql.ARRAY ) return java.math.BigDecimal';
  4  /

Function created.

ops$tkyte%ORA11GR2> drop table t;

Table dropped.

ops$tkyte%ORA11GR2> create table t ( x int, y int, z long raw );

Table created.

ops$tkyte%ORA11GR2> insert into t values ( 1, 2, '0a0a0a0a' );

1 row created.

ops$tkyte%ORA11GR2> select x, y, long_raw_length('select z from t where x = ? and y = ?', sys.odciVarchar2List(x,y) ) lrl
  2    from t;

         X          Y        LRL
---------- ---------- ----------
         1          2          4

new code modified function in Java

Enzo Viza, May 27, 2011 - 12:23 pm UTC

i had the problems with rows nulls in long_raw, i modified the code,

create or replace and compile java source named "long_raw" as
import java.io.*;
import java.lang.*;
import java.sql.*;
import java.util.*;
import oracle.jdbc.driver.*;
import java.math.*;

public class long_raw
{
public static java.math.BigDecimal getlength(java.lang.String p_query, oracle.sql.ARRAY p_binds) throws Exception
{
int length;
int tot_length = 0;
Connection conn = DriverManager.getConnection("jdbc:default:connection:");
PreparedStatement pstmt = conn.prepareStatement(p_query);
String[] binds = (String[])p_binds.getArray();
for( int i = 0; i < p_binds.length(); i++ )
{
pstmt.setString( i+1, binds[i] );
}
ResultSet rset = pstmt.executeQuery();

if ( rset.next() )
{

InputStream is = rset.getBinaryStream(1);
byte buffer[] = new byte[1024];

length = 0;
if(is != null){
while ((length = is.read (buffer,0,1024)) != -1){
length = is.read (buffer,0,1024);
tot_length += length;
}

is.close();
}
}
rset.close();
pstmt.close();
return new java.math.BigDecimal( tot_length );
}
}




Thanks Tom

long raw

A reader, September 16, 2011 - 6:32 am UTC

hi Tom,I just want to know whether there is a way to see the long raw datas with SQL statements
Tom Kyte
September 16, 2011 - 2:13 pm UTC

sure, just select it. SQLPlus has chosen to not deal with them is all - you can select them and print them out in your own programs anyway you want to.

need the code

A reader, March 05, 2012 - 1:17 pm UTC

Tom,
Could you please publish the entire java code to copy the data from a table containg long raw to another table in this website?
Tom Kyte
March 05, 2012 - 3:43 pm UTC

export/import (data pump) will do that. You can do that entirely in plsql using the dbms_datapump api.

I don't have java code to do that, if you want that - you'll need find a java coder :)

question

A reader, March 06, 2012 - 7:38 am UTC

I don't have 10g. I have 9i database. Can I do with simple exp/imp utilities?

Tom Kyte
March 06, 2012 - 7:39 am UTC

did you read the original answer? It was from 8i and described how to use exp/imp to do this...

question

A reader, March 07, 2012 - 1:17 pm UTC

Tom,
I have an application that manipulates long raw. If the column is changed to CLOB or BLOB, can the application function as it's without change or we need to make changes to the application as well?

Appreciate your answer.

Tom Kyte
March 07, 2012 - 7:10 pm UTC

In theory, you can.

In practice, you might find something that needs to be tweaked to make it work entirely.

Saving query result - log raw datatype

saeed, August 12, 2012 - 3:54 am UTC

hi
i have a table (pictures)in my oracle database , that have so many images . i want to write a query and saving query result into a file (saving each image in a file) . can you help me ?
Tom Kyte
August 17, 2012 - 1:48 pm UTC

you will have to write a program to do this, not just a query.

restore the size of table space

Hanan Majed Algammal, August 17, 2021 - 7:30 am UTC

I have two tables every one has field of long row the images in these fields were very huge
now we reduce the sizes of these images
How can restore the free size after reducing?
Connor McDonald
August 18, 2021 - 5:54 am UTC

Check out the COPY command

https://asktom.oracle.com/Misc/MoveLongs.html

You'd need to copy the data to a new table and then rename it.,

Better - look at moving to CLOB/BLOB.

LONG RAW is just problems all the time.

WORKED PERFECTLY

A reader, May 20, 2022 - 3:49 pm UTC

Worked like a CHAMP. Thanks Tom!
Connor McDonald
May 23, 2022 - 3:46 am UTC

glad we could help

More to Explore

CLOB/BLOB/etc

Complete documentation on Securefiles and Large Objects here