Naveen
Naveen

Reputation: 197

Converting Long to Varchar2

I am trying to insert into varchar2 column from a long column. here is the below example, TEXT.TEXT_COL = VARCHAR2(4000) and NOTE.TEXT_NOTE = LONG.

INSERT INTO TEXT(ROW_ID, TEXT_COL)
SELECT 1, TEXT_NOTE FROM NOTE; 

When i run the above sql i get error

SQL Error: ORA-00997: illegal use of LONG datatype

I used TO_LOB() too, but still the same error.

Is there any function which simply coverts long and put it in varchar2. Let me know your thoughts.

Upvotes: 12

Views: 135746

Answers (3)

ildar
ildar

Reputation: 109

you can use standard function to convert long to varchar2:

sys.DBMS_METADATA_UTIL.long2varchar

or to clob:

sys.DBMS_METADATA_UTIL.long2clob

Upvotes: -1

garbuya
garbuya

Reputation: 69

It looks like Oracle internally converts LONG to something else (probably CLOB) when you select LONG in FOR loop. I did not find any explanations in Oracle documentation, but this works

BEGIN
  FOR V IN (SELECT ROWID,TEXT_NOTE FROM NOTE)
  LOOP
    INSERT INTO TEXT VALUES(V.ROWID, SUBSTR(V.TEXT_NOTE, 1, 4000) );   
  END LOOP;
  COMMIT;
END;

This is an example how to copy all views from another schema to your schema

BEGIN
  FOR V IN (SELECT VIEW_NAME, TEXT_LENGTH, TEXT FROM ALL_VIEWS WHERE OWNER = 'PROD')
  LOOP
    EXECUTE IMMEDIATE 'CREATE OR REPLACE FORCE VIEW '||V.VIEW_NAME||' AS '||SUBSTR(V.TEXT, 1, V.TEXT_LENGTH);
    DBMS_OUTPUT.PUT_LINE('View '||V.VIEW_NAME||' created');
  END LOOP;
END;

For some reason it only works for FOR loop and does not work if you use WITH or select from another query

INSERT INTO TEXT
WITH V AS(SELECT ROWID ROW_ID,TEXT_NOTE FROM NOTE)
SELECT V.ROW_ID, SUBSTR(V.TEXT_NOTE, 1, 4000) FROM V; 

INSERT INTO TEXT
SELECT ROW_ID, SUBSTR(TEXT_NOTE, 1, 4000) 
FROM (SELECT ROWID ROW_ID,TEXT_NOTE FROM NOTE); 

Both inserts raise the same error

ORA-00932: inconsistent datatypes: expected CHAR got LONG

Upvotes: 2

Martin
Martin

Reputation: 219

Converting from long to varchar2 right away using a single statement is not possible, as long has certain restrictions.

You can either Create a temporary table or use PL/SQL code to solve your problem:

  • Temporary Table:

    CREATE TABLE TABLE2 AS SELECT TO_LOB(COLUMN1) COLUMN FROM TABLE1;

  • PL/SQL Code:

    DECLARE
      VAR1 LONG;
      VAR2 VARCHAR2(4000);
    BEGIN
      SELECT TEXT INTO VAR1 FROM USER_VIEWS WHERE ROWNUM = 1;  
      VAR2 := SUBSTR(VAR1, 1, 4000);
      DBMS_OUTPUT.PUT_LINE(VAR2);
    END;
    

Upvotes: 18

Related Questions