---
title: "Move an Oracle export to another version"
description: "Convert a SQL Developer or SQLcl export from Oracle 11g or later into a script that loads on Oracle 19c and later, with the same tables, keys and data."
canonical: https://intosql.com/oracle-to-oracle
last_updated: 2026-10-15
---

# Move an Oracle export to another version

Drop the .sql file SQL Developer's Database Export or SQLcl writes, with its tables and Insert statements, and download a script that loads on Oracle 19c and later. NUMBER, DATE, TIMESTAMP, LOBs, identities and sequences stay as they are, XMLTYPE and JSON keep their text in a CLOB, and every change is listed in the report.

[Oracle to Oracle migration guide](https://intosql.com/docs/migrations/oracle-to-oracle)

[Oracle to Oracle data types](https://intosql.com/docs/types/oracle-to-oracle)

## What changes between the file and the script

Each row is a rule the converter applies, with the report line it writes when the rule changes something in your data.

| In the file | In the script | Report line |
| --- | --- | --- |
| BOOLEAN (23ai) | BOOLEAN on 23ai, else NUMBER(1) with a CHECK of 0 and 1 |  |
| VARCHAR2(n BYTE|CHAR), NVARCHAR2(n), CHAR(n), NCHAR(n), CLOB, NCLOB, LONG | the same types, with their BYTE or CHAR lengths |  |
| VARCHAR2 and NVARCHAR2 past what the target's own types hold | VARCHAR2(4000 CHAR) when every value fits 4000 bytes, else CLOB | `text_as_lob` |
| NUMBER, NUMBER(p,s), FLOAT(b) | the same NUMBER types |  |
| INTERVAL YEAR TO MONTH, INTERVAL DAY TO SECOND | the same INTERVAL types |  |
| DATE, TIMESTAMP(p) | DATE and TIMESTAMP(p), as declared |  |
| TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE | the same types |  |
| JSON (21c), and CLOB holding JSON | JSON on 21c and later, else CLOB |  |
| BLOB, RAW(n), LONG RAW | the same types; LONG RAW as BLOB |  |
| ROWID, UROWID, XMLTYPE, SDO_GEOMETRY | CLOB with their text | `type_replaced` |
| collations that ignore case (BINARY_CI) | exact comparison | `case_insensitive_collation` |
| identity columns, and a sequence a BEFORE INSERT trigger assigns | GENERATED BY DEFAULT ON NULL AS IDENTITY, continuing after the highest id |  |
| identity columns the target can't count | a plain integer | `counter_dropped` |
| CREATE SEQUENCE | CREATE SEQUENCE with the same options |  |
| virtual columns (GENERATED ALWAYS AS ... VIRTUAL) | virtual columns | `stored_as_virtual` |
| virtual columns with functions IntoSQL doesn't write, and the || operator | a plain column | `generated_not_translated` |
| defaults with functions IntoSQL doesn't write (SYS_GUID(), ||) | no default | `default_not_translated` |
| CHECK constraints | translated |  |
| CHECK constraints with functions IntoSQL doesn't write | not created | `check_skipped` |
| CHECK constraints that are DISABLE or ENABLE NOVALIDATE | not created | `check_not_enforced` |
| function-based, bitmap and domain indexes | not created | `index_skipped` |
| foreign keys | after the data ENABLE NOVALIDATE, then validated with a warning on orphans |  |
| ON DELETE CASCADE that cascades in a cycle or along a second path | dropped | `foreign_key_action_unsupported` |
| foreign keys to tables the export doesn't create, and DISABLE or NOVALIDATE ones | not created | `foreign_key_skipped` |
| names longer than Oracle 12.1 allows | shortened | `name_shortened` |
| partitioned tables | one table with every partition's rows | `partitions_dropped` |
| several schemas in one export | one schema, tables named after their schema first | `schemas_merged` |
| NOT NULL columns with values that become NULL | NOT NULL dropped | `not_null_relaxed` |
| views, synonyms, types, packages, procedures, functions and other triggers | listed in the report | `not_converted_objects` |
| exports without CREATE TABLE (data only) | types read from the values | `no_schema` |
| expressions in INSERT values other than the ones exports write | NULL | `expression_value` |
| types IntoSQL doesn't know, and object types | CLOB | `unknown_type` |
| dates before year 1 and time zones given as region names | NULL | `date_out_of_range` |
| NaN and Infinity in BINARY_FLOAT and BINARY_DOUBLE | NaN and Infinity kept |  |
| NUL characters in text | kept |  |
| text that isn't valid in its encoding | the bad bytes as the replacement character | `invalid_utf8_replaced` |
| text decoded twice (Ã±) | copied as it is | `mojibake_suspected` |

## Load the script into Oracle

The script creates the tables, copies the rows, then adds keys, indexes and foreign keys, so it loads fast and stops at the first error.

```shell
NLS_LANG=.AL32UTF8 sqlplus -S -L user@//localhost/mydb @oracle.oracle.sql
```

Foreign keys are added ENABLE NOVALIDATE, so new rows are checked at once, and then validated. If an old row points to a row that doesn't exist, the script says which constraint and leaves it unvalidated, instead of failing half way.

For a large dump, run SQL*Plus on the same machine as the database. The script commits every 100 rows. The user that runs it needs CREATE TABLE, CREATE SEQUENCE, CREATE TRIGGER and CREATE PROCEDURE, and quota on its tablespace.

## Dump Oracle for the best result

The converter reads what the dump holds. These options keep more of your data in it:

- In SQL Developer, choose Tools, Database Export, with DDL and the Insert data format. SQLcl writes the same with SET SQLFORMAT INSERT.
- Run ALTER SESSION SET NLS_DATE_FORMAT = 'SYYYY-MM-DD HH24:MI:SS' before exporting: the default format writes dates without their time or century.
- A .dmp file from exp or expdp is binary: import it into an Oracle database, Oracle Database Free in Docker for one, and export it with SQL Developer.

## What isn't converted

Views, triggers, procedures, functions and other objects written in Oracle's own language are listed in the report by name, never dropped silently, so you can check each one against the Oracle version you load into before recreating it.

## Questions about moving Oracle between versions

### Is my dump uploaded?

No. The converter runs in your browser and reads the dump from your disk in pieces, so it never leaves your computer. The desktop app and the command line convert on your computer too.

### How large can the dump be?

The converter never holds the whole dump in memory: it reads the file twice, by ranges, and writes the script as it goes. Multi-gigabyte dumps convert in the browser, in the desktop app and with the command line.

### Can I convert a .dmp file from exp or expdp?

Not directly: Data Pump and the original Export write a binary format only Oracle reads. Import it into any Oracle database, Oracle Database Free runs in Docker, and export it with SQL Developer's Database Export or SQLcl. The converter says so when it gets a .dmp file.

### Which Oracle versions can the export come from?

Exports from SQL Developer and SQLcl, with DBMS_METADATA's table definitions, from Oracle 11g on. Every test export comes from Oracle 21c and 23ai, in American, German and ISO sessions, and is compared with its source cell by cell.

### What happens to NUMBER, DATE and the other Oracle types?

They stay as they are: NUMBER with its precision, DATE, TIMESTAMP, intervals, CHAR and VARCHAR2 with their lengths, RAW and the LOBs. XMLTYPE and JSON keep their text in a CLOB, so the script loads on 19c.

### Are identity columns and sequences kept?

Yes. Identity columns and sequences stay as they are and continue from where the export says they reached.

### What about PL/SQL packages, procedures and triggers?

They are listed in the report by name and not converted, so you can recreate them once the tables are in.

### Which Oracle versions does the script load on?

Oracle 19c and later. Every test export loads on 21c and 23ai, stopping at the first error if anything goes wrong.

## From Oracle

- [Oracle to PostgreSQL](https://intosql.com/oracle-to-postgresql)
- [Oracle to MySQL](https://intosql.com/oracle-to-mysql)
- [Oracle to MariaDB](https://intosql.com/oracle-to-mariadb)
- [Oracle to SQLite](https://intosql.com/oracle-to-sqlite)
- [Oracle to SQL Server](https://intosql.com/oracle-to-sql-server)

## Into Oracle

- [MySQL to Oracle](https://intosql.com/mysql-to-oracle)
- [MariaDB to Oracle](https://intosql.com/mariadb-to-oracle)
- [PostgreSQL to Oracle](https://intosql.com/postgresql-to-oracle)
- [SQL Server to Oracle](https://intosql.com/sql-server-to-oracle)
- [SQLite to Oracle](https://intosql.com/sqlite-to-oracle)

## Guide and every pair

- [Oracle to Oracle migration guide](https://intosql.com/docs/migrations/oracle-to-oracle)
- [Oracle to Oracle data types](https://intosql.com/docs/types/oracle-to-oracle)
- [Every database pair](https://intosql.com/database-migration)
