Saltar al contenido
Inicio de IntoSQL

Convierte SQL Server a Oracle

Suelta el script que escribe Generate Scripts de SSMS con esquema y datos, en .sql o .sql.gz, UTF-16 o UTF-8, y descarga un script de Oracle con las mismas tablas, claves, índices y datos. Cada valor que Oracle no puede guardar tal cual, y cada objeto que no admite, aparece en el informe.

Tu archivo
sqlshop_2024_sqlserver.sqlArchivo de ejemplo, 11 kB
Tu base de datos

18 filas convertidas, 2 correcciones, ninguna rechazada

Mostrar

Tablas en shop_2024_sqlserver.sqlVolcado de SQL Server · escrito por SQL Server Management Objects · utf-8

  • ordersescrita como ORDERS10 filas1
    11 columnas
    IDNUMBER(10) not null
    CUSTOMER_IDNUMBER(10) not null
    STATUSVARCHAR2(10 CHAR) not null
    TOTALNUMBER(19,4) not null
    ITEMSNUMBER(3) not null
    ORDERED_ATTIMESTAMP(0) not null
    SHIPPED_ATTIMESTAMP(7)
    NOTECLOB
    DETAILSCLOB
    ORDER_REFVARCHAR2(36 CHAR) not null
    TOTAL_WITH_TAXNUMBER(12,2)
  • customersescrita como CUSTOMERS8 filas1
    8 columnas
    IDNUMBER(10) not null
    NAMEVARCHAR2(100 CHAR) not null
    EMAILVARCHAR2(200 CHAR) not null
    COUNTRYVARCHAR2(2 CHAR) not null
    IS_ACTIVENUMBER(1) not null
    SIGNED_UPDATE
    CREATED_ATTIMESTAMP(0) WITH TIME ZONE not null
    ROW_VERSIONRAW(8)

Sin convertir

  • Vista paid_orders
  • Disparador orders_no_negative

Cada base de datos los escribe en su propio lenguaje. Reescríbelos para Oracle.

-- Written by IntoSQL from a SQL Server dump. Load it with: NLS_LANG=.AL32UTF8 sqlplus -S -L <user>/<password>@<database> @<file>
WHENEVER SQLERROR EXIT FAILURE ROLLBACK;
SET DEFINE OFF;
SET SQLBLANKLINES ON;
SET FEEDBACK OFF;
SET SERVEROUTPUT ON;
CREATE OR REPLACE FUNCTION "INTOSQL_CLOB" (p SYS.ODCIVARCHAR2LIST) RETURN CLOB IS
    r CLOB;
BEGIN
    DBMS_LOB.CREATETEMPORARY(r, TRUE);
    FOR i IN 1 .. p.COUNT LOOP
        IF p(i) IS NOT NULL THEN
            DBMS_LOB.WRITEAPPEND(r, LENGTH2(p(i)), p(i));
        END IF;
    END LOOP;
    RETURN r;
END;
/
CREATE OR REPLACE FUNCTION "INTOSQL_BLOB" (p SYS.ODCIVARCHAR2LIST) RETURN BLOB IS
    r BLOB;
    piece RAW(2000);
BEGIN
    DBMS_LOB.CREATETEMPORARY(r, TRUE);
    FOR i IN 1 .. p.COUNT LOOP
        piece := HEXTORAW(p(i));
        DBMS_LOB.WRITEAPPEND(r, UTL_RAW.LENGTH(piece), piece);
    END LOOP;
    RETURN r;
END;
/

CREATE TABLE "ORDERS" (
    "ID" NUMBER(10) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 1),
    "CUSTOMER_ID" NUMBER(10) NOT NULL,
    "STATUS" VARCHAR2(10 CHAR) DEFAULT 'pending' NOT NULL,
    "TOTAL" NUMBER(19,4) NOT NULL,
    "ITEMS" NUMBER(3) DEFAULT 1 NOT NULL,
    "ORDERED_AT" TIMESTAMP(0) NOT NULL,
    "SHIPPED_AT" TIMESTAMP(7),
    "NOTE" CLOB,
    "DETAILS" CLOB,
    "ORDER_REF" VARCHAR2(36 CHAR) NOT NULL,
    "TOTAL_WITH_TAX" NUMBER(12,2) GENERATED ALWAYS AS (CAST(CAST("TOTAL" * (1.16) AS NUMBER(12,2)) AS NUMBER(12,2))) VIRTUAL,
    CONSTRAINT "CK_ORDERS_ITEMS" CHECK ("ITEMS" >= 0),
    CONSTRAINT "CHECK2" CHECK ("STATUS" = 'cancelled' OR "STATUS" = 'shipped' OR "STATUS" = 'paid' OR "STATUS" = 'pending'),
    CONSTRAINT "CHECK3" CHECK ("TOTAL" >= (0))
);

CREATE TABLE "CUSTOMERS" (
    "ID" NUMBER(10) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 1),
    "NAME" VARCHAR2(100 CHAR) NOT NULL,
    "EMAIL" VARCHAR2(200 CHAR) NOT NULL,
    "COUNTRY" VARCHAR2(2 CHAR) DEFAULT 'US' NOT NULL,
    "IS_ACTIVE" NUMBER(1) DEFAULT 1 NOT NULL,
    "SIGNED_UP" DATE,
    "CREATED_AT" TIMESTAMP(0) WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL,
    "ROW_VERSION" RAW(8),
    CONSTRAINT "CK_CUSTOMERS_IS_ACTIVE" CHECK ("IS_ACTIVE" IN (0, 1))
);

BEGIN
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
1,
'Ana Martínez',
'ana@example.com',
'MX',
1,
DATE '2023-01-15',
TIMESTAMP '2023-01-15 04:24:00.0000000 -06:00'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
2,
'Zoë Müller',
'zoe@example.de',
'DE',
1,
DATE '2023-02-03',
TIMESTAMP '2023-02-03 09:11:42.0000000 +01:00'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
3,
'José Peña',
'jose@example.es',
'ES',
0,
DATE '2023-03-21',
TIMESTAMP '2023-03-21 20:05:17.0000000 +01:00'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
4,
'李雷',
'lilei@example.cn',
'CN',
1,
DATE '2023-05-09',
TIMESTAMP '2023-05-09 10:40:00.0000000 +08:00'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
5,
'Noah O''Brien',
'noah@example.ie',
'IE',
1,
NULL,
TIMESTAMP '2023-06-30 15:00:00.0000000 +01:00'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
6,
'Amélie Laurent',
'amelie@example.fr',
'FR',
1,
DATE '2024-01-02',
TIMESTAMP '2024-01-02 10:30:00.0000000 +01:00'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
7,
'Ravi Patel',
'ravi@example.in',
'IN',
0,
DATE '2024-02-29',
TIMESTAMP '2024-03-01 05:29:59.0000000 +05:30'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
8,
'Sofia Rossi 🌻',
'sofia@example.it',
'IT',
1,
DATE '2024-04-12',
TIMESTAMP '2024-04-12 14:12:12.0000000 +02:00'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
1,
1,
'shipped',
129.9000,
3,
TIMESTAMP '2024-03-01 10:00:00.0000000',
TIMESTAMP '2024-03-02 16:30:00.1234567',
NULL,
'{"gift": false}',
'0b7a4c2e-3f1d-4e8a-9c55-1a2b3c4d5e6f'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
2,
2,
'paid',
54.0000,
1,
TIMESTAMP '2024-03-02 11:15:00.0000000',
NULL,
'Gift wrap 🎁',
'{"gift": true, "wrap": "red"}',
'1c8b5d3f-4a2e-4f9b-8d66-2b3c4d5e6f70'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
3,
1,
'cancelled',
12.5000,
1,
TIMESTAMP '2024-03-03 09:45:00.0000000',
NULL,
'Customer changed their mind',
NULL,
'2d9c6e4a-5b3f-4a0c-9e77-3c4d5e6f7081'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
4,
4,
'shipped',
980.0000,
12,
TIMESTAMP '2024-03-05 02:10:00.0000000',
TIMESTAMP '2024-03-07 08:00:00.0000000',
'请小心轻放',
'{"fragile": true}',
'3e0d7f5b-6c4a-4b1d-8f88-4d5e6f708192'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
5,
5,
'pending',
45.7500,
2,
TIMESTAMP '2024-03-08 17:20:00.0000000',
NULL,
'Leave at the door; ring twice',
NULL,
'4f1e806c-7d5b-4c2e-9a99-5e6f708192a3'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
6,
6,
'shipped',
310.4000,
5,
TIMESTAMP '2024-03-10 13:00:00.0000000',
TIMESTAMP '2024-03-11 09:00:00.0000000',
'Fragile: "glass"',
'{"fragile": true}',
'50f2917d-8e6c-4d3f-8baa-6f708192a3b4'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
7,
8,
'paid',
76.2000,
2,
TIMESTAMP '2024-03-11 18:45:00.0000000',
NULL,
NULL,
NULL,
'6103a28e-9f7d-4e40-9cbb-708192a3b4c5'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
8,
2,
'shipped',
19.9900,
1,
TIMESTAMP '2024-03-12 08:00:00.0000000',
TIMESTAMP '9999-12-31 23:59:59.9999999',
'Shipped date set to the maximum by an old import',
NULL,
'7214b39f-a08e-4f51-8dcc-8192a3b4c5d6'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
9,
3,
'shipped',
64.0000,
2,
TIMESTAMP '2024-03-14 15:30:00.0000000',
TIMESTAMP '2024-03-15 10:00:00.0000000',
'Two parcels',
'{"parcels": [1, 2]}',
'8325c4a0-b19f-4062-9edd-92a3b4c5d6e7'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
10,
7,
'paid',
1499.0000,
1,
TIMESTAMP '2024-03-15 21:05:00.0000000',
NULL,
'C:\Users\ravi\invoice.pdf',
NULL,
'9436d5b1-c2a0-4173-8fee-a3b4c5d6e7f8'
);
COMMIT;
END;
/

-- Keys, indexes, foreign keys, counters and triggers, after the rows.
ALTER TABLE "ORDERS" ADD CONSTRAINT "PK_ORDERS" PRIMARY KEY ("ID");
ALTER TABLE "CUSTOMERS" ADD CONSTRAINT "PK_CUSTOMERS" PRIMARY KEY ("ID");
ALTER TABLE "CUSTOMERS" ADD CONSTRAINT "UQ_CUSTOMERS_EMAIL" UNIQUE ("EMAIL");
CREATE INDEX "IX_ORDERS_IDX_ORDERS_CUSTOMER" ON "ORDERS" ("CUSTOMER_ID");
CREATE INDEX "IX_ORDERS_IDX_ORDERS_STATUS_DATE" ON "ORDERS" ("STATUS", "ORDERED_AT");
ALTER TABLE "ORDERS" ADD CONSTRAINT "FK_ORDERS" FOREIGN KEY ("CUSTOMER_ID") REFERENCES "CUSTOMERS" ("ID") ENABLE NOVALIDATE;
BEGIN
    EXECUTE IMMEDIATE 'ALTER TABLE "ORDERS" ENABLE VALIDATE CONSTRAINT "FK_ORDERS"';
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('Foreign key ' || '"FK_ORDERS"' || ' has rows without a parent: it stays unvalidated, and new rows are checked.');
END;
/
DECLARE
    next_id NUMBER;
BEGIN
    SELECT NVL(MAX("ID"), 0) + 1 INTO next_id FROM "ORDERS";
    IF next_id < 1 THEN
        next_id := 1;
    END IF;
    EXECUTE IMMEDIATE 'ALTER TABLE "ORDERS" MODIFY ("ID" GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH ' || next_id || '))';
END;
/
DECLARE
    next_id NUMBER;
BEGIN
    SELECT NVL(MAX("ID"), 0) + 1 INTO next_id FROM "CUSTOMERS";
    IF next_id < 1 THEN
        next_id := 1;
    END IF;
    EXECUTE IMMEDIATE 'ALTER TABLE "CUSTOMERS" MODIFY ("ID" GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH ' || next_id || '))';
END;
/
COMMENT ON TABLE "CUSTOMERS" IS 'People who bought at least once';
DROP FUNCTION "INTOSQL_CLOB";
DROP FUNCTION "INTOSQL_BLOB";
COMMIT;
EXIT;

Correcciones

  1. "total_with_tax" de orders se guarda en el origen; Oracle la calcula al leer.
  2. "row_version" de customers es una versión de fila que SQL Server asigna por sí mismo; el volcado no tiene valores para ella, así que es RAW(8) y queda vacía.

Para revisar

  • 6 columnas de texto comparan sin distinguir mayúsculas en el origen; Oracle compara exactamente, así que las claves únicas y las búsquedas pueden comportarse distinto. Usa una intercalación o un tipo de columna que no distinga mayúsculas en las columnas que lo necesiten.
  • 2 vistas, disparadores, rutinas o eventos no se convierten; el informe lista cada uno. Vuelve a crearlos a mano en Oracle.
  • El CHECK check1 de orders no se puede escribir para Oracle (function isjson), así que no se crea. Escribe el CHECK a mano si es importante.
  • El índice idx_orders_pending de orders usa una expresión que no se puede escribir para Oracle (filtered index), así que no se crea. Crea el índice a mano si las consultas lo necesitan.
  • El valor predeterminado de "order_ref" en orders no se puede escribir para Oracle (function uuid), así que la columna no tiene valor predeterminado. Agrega el valor predeterminado a mano si las filas nuevas lo necesitan.

Tu archivo se convierte en esta computadora y nunca se sube.

Otros ejemplos:

Qué cambia de SQL Server a Oracle

Cada fila es una regla que aplica el convertidor, con la línea que escribe en el informe cuando la regla cambia algo en tus datos.

  • bit

    NUMBER(1) con un CHECK de 0 y 1

    Oracle 21c no tiene un tipo de columna booleano; 1 y 0 conservan los valores en cada versión.

  • char(n), varchar(n), nchar(n), nvarchar(n)

    VARCHAR2(n CHAR), contando caracteres

    Las longitudes cuentan caracteres, como el nvarchar de SQL Server.

  • varchar(max), nvarchar(max), text, ntext

    VARCHAR2(4000 CHAR) cuando cada valor cabe en 4000 bytes, si no CLOB

    Un VARCHAR2 admite 4000 bytes por defecto y Oracle no puede indexar un CLOB, así que el texto se queda en VARCHAR2 cuando sus valores caben y es un CLOB cuando no.

    Línea del informe: text_as_lob

  • empty strings and empty binary values

    NULL

    Oracle guarda una cadena vacía como NULL, así que un valor que era ' se lee como NULL. El informe los cuenta por columna.

    Línea del informe: empty_string_null

  • decimal(p,s), money, smallmoney

    NUMBER(p,s); money como NUMBER(19,4)

    NUMBER admite 38 dígitos, como decimal, así que cada valor es exacto.

  • datetime, datetime2, smalldatetime

    TIMESTAMP(p)

    Un datetime es una lectura de reloj, como el TIMESTAMP de Oracle, que guarda hasta nueve dígitos de segundo. date se vuelve DATE, que también guarda una hora del día que se queda en medianoche.

  • datetimeoffset

    TIMESTAMP WITH TIME ZONE, con el desfase de cada valor

    Oracle conserva los desfases de -12:00 a +14:00; un valor con un desfase más allá de -12:00 se escribe en UTC, el mismo instante.

  • time

    INTERVAL DAY TO SECOND desde la medianoche

    Oracle no tiene un tipo para la hora del día; un intervalo desde medianoche admite cada valor.

  • dates that aren't valid

    NULL

    Un valor que no es una fecha se vuelve NULL y el informe lo cuenta.

    Línea del informe: date_out_of_range

  • json (SQL Server 2025)

    CLOB

    Los mismos valores JSON, que leen las funciones JSON de Oracle.

  • uniqueidentifier

    VARCHAR2(36)

    Los mismos identificadores, escritos en minúsculas.

  • binary, varbinary, image

    RAW(n) y BLOB

    Los bytes siguen siendo bytes.

  • geometry, geography

    BLOB con los bytes propios de SQL Server

    SSMS escribe los valores espaciales en la serialización de SQL Server, que se conserva byte a byte.

    Línea del informe: spatial_as_native

  • rowversion, timestamp

    BLOB, sin valores

    SQL Server asigna la versión de fila por sí mismo y SSMS no escribe valores para ella en el script.

    Línea del informe: rowversion_empty

  • xml, sql_variant, hierarchyid, vector

    VARCHAR2 o CLOB con el texto de cada valor

    Oracle no tiene un tipo equivalente; xml y sql_variant conservan el texto de cada valor y hierarchyid su ruta, como /1/2/.

    Línea del informe: type_replaced

  • collations that ignore case (_CI_)

    comparación exacta

    Oracle compara el texto exactamente salvo que se indique otra cosa, así que las columnas que no distinguían mayúsculas en SQL Server ahora distinguen Ana de ana.

    Línea del informe: case_insensitive_collation

  • IDENTITY

    GENERATED BY DEFAULT ON NULL AS IDENTITY, siguiendo después del id más alto

    Los ids copiados se cargan tal cual, y el contador sigue después del más alto.

  • CREATE SEQUENCE

    CREATE SEQUENCE con las mismas opciones

    Las secuencias de Oracle funcionan de la misma forma. SSMS no escribe hasta dónde llegó una secuencia, así que empieza donde se creó.

  • computed columns

    columnas virtuales

    Oracle solo calcula las columnas generadas al leer; las columnas PERSISTED se vuelven virtuales con los mismos valores.

    Línea del informe: stored_as_virtual

  • computed columns with functions Oracle lacks

    una columna simple

    Una fórmula que no se puede escribir deja una columna simple y una línea en el informe; SSMS no escribe valores para las columnas calculadas.

    Línea del informe: generated_not_translated

  • defaults with functions Oracle lacks, and NEXT VALUE FOR

    sin valor predeterminado

    Un valor predeterminado que no se puede escribir se deja fuera y aparece en el informe.

    Línea del informe: default_not_translated

  • CHECK constraints

    traducidos

    Los mismos CHECK, comprobados al cargar cada fila.

  • CHECK constraints with functions Oracle lacks

    no se crea

    Un CHECK que no se puede escribir se deja fuera y aparece en el informe.

    Línea del informe: check_skipped

  • CHECK constraints added WITH NOCHECK or disabled

    no se crea

    SQL Server no aplica estos CHECK, así que las filas pueden no cumplirlos.

    Línea del informe: check_not_enforced

  • filtered and columnstore indexes, and indexes on CLOB columns

    no se crea

    IntoSQL escribe índices b-tree sobre columnas completas; vuelve a crear los demás después de cargar.

    Línea del informe: index_skipped

  • foreign keys

    después de los datos, ENABLE NOVALIDATE, luego validada con una advertencia si hay huérfanas

    La clave comprueba las filas nuevas de inmediato y se valida al final; las filas sin padre la dejan sin validar con una advertencia en lugar de detener la carga.

  • ON UPDATE CASCADE, SET NULL or SET DEFAULT; ON DELETE SET DEFAULT

    se descarta

    Las claves foráneas de Oracle solo actúan al eliminar, con CASCADE o SET NULL.

    Línea del informe: foreign_key_action_unsupported

  • names over 128 bytes

    acortado

    En Oracle 12.2 y posteriores los nombres admiten 128 bytes; los de SQL Server admiten 128 caracteres.

    Línea del informe: name_shortened

  • foreign keys to tables the dump doesn't create

    no se crea

    Una clave no puede nombrar una tabla que no existe.

    Línea del informe: foreign_key_skipped

  • tables on a partition scheme

    una tabla con las filas de todas las particiones

    Las filas son las mismas; vuelve a particionar la tabla en Oracle si lo necesita.

    Línea del informe: partitions_dropped

  • temporal tables (SYSTEM_VERSIONING)

    dos tablas: las filas actuales y el historial

    La tabla y su tabla de historial se copian como tablas simples; Oracle no conserva el historial por sí mismo.

    Línea del informe: system_versioning_dropped

  • schemas

    un esquema, con el nombre del esquema delante de cada tabla

    El script se carga en el esquema del usuario que lo ejecuta, así que las tablas de esquemas distintos llevan delante el nombre de su esquema; las tablas de dbo conservan sus nombres.

    Línea del informe: schemas_merged

  • NOT NULL columns with values that become NULL

    sin NOT NULL

    Una columna cuyos valores tuvieron que volverse NULL no puede conservar NOT NULL, o la carga se detendría.

    Línea del informe: not_null_relaxed

  • views, functions, procedures, triggers, synonyms, types and partition functions

    listados en el informe

    Su código está escrito en T-SQL, así que se listan para que los vuelvas a crear.

    Línea del informe: not_converted_objects

  • scripts without CREATE TABLE (data only)

    tipos leídos de los valores

    Un script solo de datos solo tiene filas, así que los tipos salen de los valores.

    Línea del informe: no_schema

  • expressions in INSERT values

    NULL

    Un convertidor que no ejecuta una base de datos no puede evaluarlas.

    Línea del informe: expression_value

  • types IntoSQL doesn't know

    CLOB

    El texto admite cualquier valor; cambia el tipo después de cargar.

    Línea del informe: unknown_type

  • NUL characters in text

    se conserva

    VARCHAR2 y CLOB pueden contener un carácter NUL, así que el valor se copia tal cual.

  • text that isn't valid in its encoding

    los bytes incorrectos como carácter de reemplazo

    El script es UTF-8 y cada valor tiene que ser texto válido.

    Línea del informe: invalid_utf8_replaced

  • text decoded twice (ñ)

    se copia tal cual

    El script contiene exactamente estos caracteres, así que se copian; el informe los señala.

    Línea del informe: mojibake_suspected

En SQL ServerEn OracleLínea del informe
bitNUMBER(1) con un CHECK de 0 y 1Oracle 21c no tiene un tipo de columna booleano; 1 y 0 conservan los valores en cada versión.
char(n), varchar(n), nchar(n), nvarchar(n)VARCHAR2(n CHAR), contando caracteresLas longitudes cuentan caracteres, como el nvarchar de SQL Server.
varchar(max), nvarchar(max), text, ntextVARCHAR2(4000 CHAR) cuando cada valor cabe en 4000 bytes, si no CLOBUn VARCHAR2 admite 4000 bytes por defecto y Oracle no puede indexar un CLOB, así que el texto se queda en VARCHAR2 cuando sus valores caben y es un CLOB cuando no.text_as_lob
empty strings and empty binary valuesNULLOracle guarda una cadena vacía como NULL, así que un valor que era ' se lee como NULL. El informe los cuenta por columna.empty_string_null
decimal(p,s), money, smallmoneyNUMBER(p,s); money como NUMBER(19,4)NUMBER admite 38 dígitos, como decimal, así que cada valor es exacto.
datetime, datetime2, smalldatetimeTIMESTAMP(p)Un datetime es una lectura de reloj, como el TIMESTAMP de Oracle, que guarda hasta nueve dígitos de segundo. date se vuelve DATE, que también guarda una hora del día que se queda en medianoche.
datetimeoffsetTIMESTAMP WITH TIME ZONE, con el desfase de cada valorOracle conserva los desfases de -12:00 a +14:00; un valor con un desfase más allá de -12:00 se escribe en UTC, el mismo instante.
timeINTERVAL DAY TO SECOND desde la medianocheOracle no tiene un tipo para la hora del día; un intervalo desde medianoche admite cada valor.
dates that aren't validNULLUn valor que no es una fecha se vuelve NULL y el informe lo cuenta.date_out_of_range
json (SQL Server 2025)CLOBLos mismos valores JSON, que leen las funciones JSON de Oracle.
uniqueidentifierVARCHAR2(36)Los mismos identificadores, escritos en minúsculas.
binary, varbinary, imageRAW(n) y BLOBLos bytes siguen siendo bytes.
geometry, geographyBLOB con los bytes propios de SQL ServerSSMS escribe los valores espaciales en la serialización de SQL Server, que se conserva byte a byte.spatial_as_native
rowversion, timestampBLOB, sin valoresSQL Server asigna la versión de fila por sí mismo y SSMS no escribe valores para ella en el script.rowversion_empty
xml, sql_variant, hierarchyid, vectorVARCHAR2 o CLOB con el texto de cada valorOracle no tiene un tipo equivalente; xml y sql_variant conservan el texto de cada valor y hierarchyid su ruta, como /1/2/.type_replaced
collations that ignore case (_CI_)comparación exactaOracle compara el texto exactamente salvo que se indique otra cosa, así que las columnas que no distinguían mayúsculas en SQL Server ahora distinguen Ana de ana.case_insensitive_collation
IDENTITYGENERATED BY DEFAULT ON NULL AS IDENTITY, siguiendo después del id más altoLos ids copiados se cargan tal cual, y el contador sigue después del más alto.
CREATE SEQUENCECREATE SEQUENCE con las mismas opcionesLas secuencias de Oracle funcionan de la misma forma. SSMS no escribe hasta dónde llegó una secuencia, así que empieza donde se creó.
computed columnscolumnas virtualesOracle solo calcula las columnas generadas al leer; las columnas PERSISTED se vuelven virtuales con los mismos valores.stored_as_virtual
computed columns with functions Oracle lacksuna columna simpleUna fórmula que no se puede escribir deja una columna simple y una línea en el informe; SSMS no escribe valores para las columnas calculadas.generated_not_translated
defaults with functions Oracle lacks, and NEXT VALUE FORsin valor predeterminadoUn valor predeterminado que no se puede escribir se deja fuera y aparece en el informe.default_not_translated
CHECK constraintstraducidosLos mismos CHECK, comprobados al cargar cada fila.
CHECK constraints with functions Oracle lacksno se creaUn CHECK que no se puede escribir se deja fuera y aparece en el informe.check_skipped
CHECK constraints added WITH NOCHECK or disabledno se creaSQL Server no aplica estos CHECK, así que las filas pueden no cumplirlos.check_not_enforced
filtered and columnstore indexes, and indexes on CLOB columnsno se creaIntoSQL escribe índices b-tree sobre columnas completas; vuelve a crear los demás después de cargar.index_skipped
foreign keysdespués de los datos, ENABLE NOVALIDATE, luego validada con una advertencia si hay huérfanasLa clave comprueba las filas nuevas de inmediato y se valida al final; las filas sin padre la dejan sin validar con una advertencia en lugar de detener la carga.
ON UPDATE CASCADE, SET NULL or SET DEFAULT; ON DELETE SET DEFAULTse descartaLas claves foráneas de Oracle solo actúan al eliminar, con CASCADE o SET NULL.foreign_key_action_unsupported
names over 128 bytesacortadoEn Oracle 12.2 y posteriores los nombres admiten 128 bytes; los de SQL Server admiten 128 caracteres.name_shortened
foreign keys to tables the dump doesn't createno se creaUna clave no puede nombrar una tabla que no existe.foreign_key_skipped
tables on a partition schemeuna tabla con las filas de todas las particionesLas filas son las mismas; vuelve a particionar la tabla en Oracle si lo necesita.partitions_dropped
temporal tables (SYSTEM_VERSIONING)dos tablas: las filas actuales y el historialLa tabla y su tabla de historial se copian como tablas simples; Oracle no conserva el historial por sí mismo.system_versioning_dropped
schemasun esquema, con el nombre del esquema delante de cada tablaEl script se carga en el esquema del usuario que lo ejecuta, así que las tablas de esquemas distintos llevan delante el nombre de su esquema; las tablas de dbo conservan sus nombres.schemas_merged
NOT NULL columns with values that become NULLsin NOT NULLUna columna cuyos valores tuvieron que volverse NULL no puede conservar NOT NULL, o la carga se detendría.not_null_relaxed
views, functions, procedures, triggers, synonyms, types and partition functionslistados en el informeSu código está escrito en T-SQL, así que se listan para que los vuelvas a crear.not_converted_objects
scripts without CREATE TABLE (data only)tipos leídos de los valoresUn script solo de datos solo tiene filas, así que los tipos salen de los valores.no_schema
expressions in INSERT valuesNULLUn convertidor que no ejecuta una base de datos no puede evaluarlas.expression_value
types IntoSQL doesn't knowCLOBEl texto admite cualquier valor; cambia el tipo después de cargar.unknown_type
NUL characters in textse conservaVARCHAR2 y CLOB pueden contener un carácter NUL, así que el valor se copia tal cual.
text that isn't valid in its encodinglos bytes incorrectos como carácter de reemplazoEl script es UTF-8 y cada valor tiene que ser texto válido.invalid_utf8_replaced
text decoded twice (ñ)se copia tal cualEl script contiene exactamente estos caracteres, así que se copian; el informe los señala.mojibake_suspected

Carga el script en Oracle

El script crea las tablas, copia las filas y luego agrega claves, índices y claves foráneas, así que carga rápido y se detiene en el primer error.

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

Las claves foráneas se agregan ENABLE NOVALIDATE, así que las filas nuevas se comprueban de inmediato, y luego se validan. Si una fila antigua apunta a una fila que no existe, el script dice qué restricción es y la deja sin validar, en lugar de fallar a medias.

Para un volcado grande, ejecuta SQL*Plus en la misma máquina que la base de datos. El script confirma cada 100 filas. El usuario que lo ejecuta necesita CREATE TABLE, CREATE SEQUENCE, CREATE TRIGGER y CREATE PROCEDURE, y cuota en su tablespace.

Haz el volcado de SQL Server para el mejor resultado

El convertidor lee lo que contiene el volcado. Estas opciones conservan más de tus datos en él:

  • En SSMS, haz clic derecho en la base de datos, Tasks, Generate Scripts, y elige las tablas. dbatools, mssql-scripter y otras herramientas basadas en la misma biblioteca escriben el mismo script.
  • En Advanced, cambia Types of data to script a Schema and data. Un script solo del esquema tiene tablas sin filas.
  • Guárdalo como Unicode, el formato predeterminado de SSMS, o como UTF-8: ambos se leen igual, y gzip también funciona.

Qué no se convierte

Las vistas, funciones, procedimientos, disparadores, sinónimos, reglas y políticas de seguridad se escriben en T-SQL. Aparecen en el informe por nombre, nunca se descartan en silencio, para que puedas reescribirlos para Oracle.

Preguntas sobre SQL Server a Oracle

¿No encuentras la respuesta? Escríbenos desde la página de contacto y te responde una persona. Página de contacto

¿Se sube mi volcado?

No. El convertidor se ejecuta en tu navegador y lee el volcado de tu disco por partes, así que nunca sale de tu computadora. La app de escritorio y la línea de comandos también convierten en tu computadora.

¿Qué tan grande puede ser el volcado?

El convertidor nunca tiene todo el volcado en memoria: lee el archivo dos veces, por rangos, y escribe el script sobre la marcha. Los volcados de varios gigabytes se convierten en el navegador, en la app de escritorio y con la línea de comandos.

¿Lee el archivo UTF-16 que guarda SSMS?

Sí. SSMS guarda los scripts en UTF-16 por defecto, y el convertidor lee UTF-16 y UTF-8 por igual, con gzip o sin él, con GO entre lotes.

¿De qué versiones de SQL Server puede venir el script?

Scripts que SSMS, dbatools o mssql-scripter escriben desde SQL Server 2017 en adelante. Cada script de prueba viene de SQL Server 2017, 2022 y 2025 y se compara con su origen celda por celda.

¿Se conservan los valores IDENTITY?

Sí. Las columnas IDENTITY se vuelven columnas de identidad, cada fila conserva su id y el siguiente id sigue después del más alto. Las secuencias se crean con las mismas opciones.

¿Qué pasa con money, datetimeoffset y otros tipos de SQL Server?

bit se vuelve NUMBER(1), datetime2 TIMESTAMP con cada dígito, datetimeoffset TIMESTAMP WITH TIME ZONE con su desfase, y nvarchar(max) CLOB cuando sus valores no caben en un VARCHAR2. Las cadenas vacías se vuelven NULL, como las guarda Oracle, y el informe las cuenta.

¿Qué pasa con los procedimientos, los disparadores y las vistas?

Aparecen en el informe por nombre y no se convierten, porque cada base de datos los escribe en su propio lenguaje.

¿En qué versiones de Oracle carga el script?

Oracle 19c y posteriores. Cada script de prueba carga en 21c y 23ai, y se detiene en el primer error si algo sale mal.