Zum Inhalt springen
IntoSQL-Startseite

SQL Server in Oracle umwandeln

Leg das Skript ab, das Generate Scripts in SSMS mit Schema und Daten schreibt, als .sql oder .sql.gz, UTF-16 oder UTF-8, und lade ein Oracle-Skript mit denselben Tabellen, Schlüsseln, Indizes und Daten herunter. Jeder Wert, den Oracle nicht unverändert aufnehmen kann, und jedes Objekt, das es nicht übernimmt, steht im Bericht.

Deine Datei
sqlshop_2024_sqlserver.sqlBeispieldatei, 11 kB
Deine Datenbank

18 Zeilen konvertiert, 2 Korrekturen, keine abgelehnt

Anzeigen

Tabellen in shop_2024_sqlserver.sqlSQL Server-Dump · erstellt mit SQL Server Management Objects · utf-8

  • ordersgeschrieben als ORDERS10 Zeilen1
    11 Spalten
    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)
  • customersgeschrieben als CUSTOMERS8 Zeilen1
    8 Spalten
    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)

Nicht konvertiert

  • Sicht paid_orders
  • Trigger orders_no_negative

Jede Datenbank schreibt diese in ihrer eigenen Sprache. Schreib sie für Oracle neu.

-- 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;

Korrekturen

  1. "total_with_tax" von orders wird in der Quelle gespeichert; Oracle berechnet sie beim Lesen.
  2. "row_version" von customers ist eine Zeilenversion, die SQL Server selbst setzt; der Dump hat keine Werte dafür, daher ist es RAW(8) und leer.

Zu prüfen

  • 6 Textspalten vergleichen in der Quelle ohne Rücksicht auf Groß- und Kleinschreibung; Oracle vergleicht exakt, daher können sich eindeutige Schlüssel und Suchen anders verhalten. Nutze eine Collation oder einen Spaltentyp ohne Unterscheidung der Groß- und Kleinschreibung für die Spalten, die das brauchen.
  • 2 Sichten, Trigger, Routinen oder Ereignisse werden nicht konvertiert; der Bericht listet sie einzeln auf. Lege sie in Oracle von Hand neu an.
  • Die CHECK-Bedingung check1 auf orders lässt sich nicht für Oracle schreiben (function isjson), daher wird sie nicht angelegt. Schreib die CHECK-Bedingung von Hand, wenn sie wichtig ist.
  • Der Index idx_orders_pending auf orders nutzt einen Ausdruck, der sich nicht für Oracle schreiben lässt (filtered index), daher wird er nicht angelegt. Lege den Index von Hand an, wenn Abfragen ihn brauchen.
  • Der Standardwert von "order_ref" in orders lässt sich nicht für Oracle schreiben (function uuid), daher hat die Spalte keinen Standardwert. Füge den Standardwert von Hand hinzu, wenn neue Zeilen ihn brauchen.

Deine Datei wird auf diesem Computer umgewandelt und nie hochgeladen.

Weitere Beispiele:

Was sich von SQL Server zu Oracle ändert

Jede Zeile ist eine Regel, die der Konverter anwendet, mit der Berichtszeile, die er schreibt, wenn die Regel etwas an deinen Daten ändert.

  • bit

    NUMBER(1) mit einem CHECK auf 0 und 1

    Oracle 21c hat keinen booleschen Spaltentyp; 1 und 0 bewahren die Werte auf jeder Version.

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

    VARCHAR2(n CHAR), in Zeichen gezählt

    Längen zählen Zeichen wie nvarchar in SQL Server.

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

    VARCHAR2(4000 CHAR), wenn jeder Wert in 4000 Bytes passt, sonst CLOB

    Ein VARCHAR2 fasst standardmäßig 4000 Bytes, und Oracle kann kein CLOB indizieren, daher behält Text VARCHAR2, wenn seine Werte passen, und wird sonst ein CLOB.

    Berichtszeile: text_as_lob

  • empty strings and empty binary values

    NULL

    Oracle speichert einen leeren String als NULL, daher wird ein Wert, der ' war, als NULL gelesen. Der Bericht zählt sie pro Spalte.

    Berichtszeile: empty_string_null

  • decimal(p,s), money, smallmoney

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

    NUMBER fasst 38 Stellen wie decimal, daher ist jeder Wert exakt.

  • datetime, datetime2, smalldatetime

    TIMESTAMP(p)

    Ein datetime ist eine Uhrzeitangabe ohne Zeitzone, wie TIMESTAMP in Oracle, das bis zu neun Nachkommastellen der Sekunde behält. date wird DATE, das auch eine Uhrzeit enthält, die auf Mitternacht bleibt.

  • datetimeoffset

    TIMESTAMP WITH TIME ZONE, mit dem Versatz jedes Werts

    Oracle behält Versätze von -12:00 bis +14:00; ein Wert mit einem Versatz jenseits von -12:00 wird in UTC geschrieben, derselbe Zeitpunkt.

  • time

    INTERVAL DAY TO SECOND ab Mitternacht

    Oracle hat keinen Uhrzeittyp; ein Intervall ab Mitternacht fasst jeden Wert.

  • dates that aren't valid

    NULL

    Ein Wert, der kein Datum ist, wird NULL, und der Bericht zählt ihn.

    Berichtszeile: date_out_of_range

  • json (SQL Server 2025)

    CLOB

    Dieselben JSON-Werte, die die JSON-Funktionen von Oracle lesen.

  • uniqueidentifier

    VARCHAR2(36)

    Dieselben Bezeichner, kleingeschrieben.

  • binary, varbinary, image

    RAW(n) und BLOB

    Bytes bleiben Bytes.

  • geometry, geography

    BLOB mit den eigenen Bytes von SQL Server

    SSMS schreibt räumliche Werte in der Serialisierung von SQL Server, die Byte für Byte erhalten bleibt.

    Berichtszeile: spatial_as_native

  • rowversion, timestamp

    BLOB, leer

    SQL Server setzt eine Zeilenversion selbst, und SSMS schreibt keine Werte dafür.

    Berichtszeile: rowversion_empty

  • xml, sql_variant, hierarchyid, vector

    VARCHAR2 oder CLOB mit dem Text jedes Werts

    Oracle hat keinen entsprechenden Typ; xml und sql_variant behalten den Text jedes Werts und hierarchyid seinen Pfad, etwa /1/2/.

    Berichtszeile: type_replaced

  • collations that ignore case (_CI_)

    exakter Vergleich

    Oracle vergleicht Text exakt, sofern nicht anders angegeben, daher unterscheiden Spalten, die in SQL Server Groß-/Kleinschreibung ignorierten, jetzt Ana und ana.

    Berichtszeile: case_insensitive_collation

  • IDENTITY

    GENERATED BY DEFAULT ON NULL AS IDENTITY, weiter nach der höchsten ID

    Die kopierten IDs laden unverändert, und der Zähler macht nach der höchsten weiter.

  • CREATE SEQUENCE

    CREATE SEQUENCE mit denselben Optionen

    Sequenzen in Oracle funktionieren genauso. SSMS schreibt nicht, wie weit eine Sequenz gekommen ist, daher beginnt sie dort, wo sie angelegt wurde.

  • computed columns

    virtuelle Spalten

    Oracle berechnet generierte Spalten nur beim Lesen; PERSISTED-Spalten werden virtuell, mit denselben Werten.

    Berichtszeile: stored_as_virtual

  • computed columns with functions Oracle lacks

    eine normale Spalte

    Eine Formel, die sich nicht schreiben lässt, hinterlässt eine normale Spalte und eine Zeile im Bericht; SSMS schreibt keine Werte für berechnete Spalten.

    Berichtszeile: generated_not_translated

  • defaults with functions Oracle lacks, and NEXT VALUE FOR

    kein Standardwert

    Ein Standardwert, der sich nicht schreiben lässt, wird weggelassen und gemeldet.

    Berichtszeile: default_not_translated

  • CHECK constraints

    übersetzt

    Dieselben CHECK-Bedingungen, geprüft beim Laden jeder Zeile.

  • CHECK constraints with functions Oracle lacks

    nicht angelegt

    Eine CHECK-Bedingung, die sich nicht schreiben lässt, wird weggelassen und gemeldet.

    Berichtszeile: check_skipped

  • CHECK constraints added WITH NOCHECK or disabled

    nicht angelegt

    SQL Server wendet diese CHECK-Bedingungen nicht an, daher können die Zeilen sie verletzen.

    Berichtszeile: check_not_enforced

  • filtered and columnstore indexes, and indexes on CLOB columns

    nicht angelegt

    IntoSQL schreibt B-Tree-Indizes auf ganze Spalten; lege die anderen nach dem Laden neu an.

    Berichtszeile: index_skipped

  • foreign keys

    nach den Daten, ENABLE NOVALIDATE, dann validiert, mit einer Warnung bei verwaisten Zeilen

    Der Schlüssel prüft neue Zeilen sofort und wird zuletzt validiert; Zeilen ohne Elternzeile lassen ihn mit einer Warnung unvalidiert, statt das Laden abzubrechen.

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

    entfernt

    Fremdschlüssel in Oracle handeln nur beim Löschen, mit CASCADE oder SET NULL.

    Berichtszeile: foreign_key_action_unsupported

  • names over 128 bytes

    gekürzt

    Namen fassen in Oracle 12.2 und neuer 128 Bytes, in SQL Server 128 Zeichen.

    Berichtszeile: name_shortened

  • foreign keys to tables the dump doesn't create

    nicht angelegt

    Ein Schlüssel kann nicht auf eine Tabelle verweisen, die es nicht gibt.

    Berichtszeile: foreign_key_skipped

  • tables on a partition scheme

    eine Tabelle mit den Zeilen aller Partitionen

    Die Zeilen sind dieselben; partitioniere die Tabelle in Oracle neu, wenn nötig.

    Berichtszeile: partitions_dropped

  • temporal tables (SYSTEM_VERSIONING)

    zwei Tabellen: die aktuellen Zeilen und die Historie

    Die Tabelle und ihre Historientabelle werden als normale Tabellen kopiert; Oracle führt die Historie nicht selbst.

    Berichtszeile: system_versioning_dropped

  • schemas

    ein Schema, jede Tabelle mit dem Namen ihres Schemas vorangestellt

    Das Skript lädt in das Schema des ausführenden Benutzers, daher bekommen Tabellen verschiedener Schemas den Namen ihres Schemas vorangestellt; Tabellen in dbo behalten ihre Namen.

    Berichtszeile: schemas_merged

  • NOT NULL columns with values that become NULL

    NOT NULL entfernt

    Eine Spalte, deren Werte NULL werden mussten, kann NOT NULL nicht behalten, sonst würde das Laden abbrechen.

    Berichtszeile: not_null_relaxed

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

    im Bericht aufgeführt

    Ihr Code ist in T-SQL geschrieben, daher werden sie aufgeführt, damit du sie neu anlegst.

    Berichtszeile: not_converted_objects

  • scripts without CREATE TABLE (data only)

    Typen aus den Werten gelesen

    Ein Skript nur mit Daten enthält nur Zeilen, daher kommen die Typen aus den Werten.

    Berichtszeile: no_schema

  • expressions in INSERT values

    NULL

    Ein Konverter, der keine Datenbank ausführt, kann sie nicht auswerten.

    Berichtszeile: expression_value

  • types IntoSQL doesn't know

    CLOB

    Text nimmt jeden Wert auf; ändere den Typ nach dem Laden.

    Berichtszeile: unknown_type

  • NUL characters in text

    erhalten

    VARCHAR2 und CLOB können ein NUL-Zeichen enthalten, daher wird der Wert unverändert kopiert.

  • text that isn't valid in its encoding

    die fehlerhaften Bytes als Ersatzzeichen

    Das Skript ist UTF-8, und jeder Wert muss gültiger Text sein.

    Berichtszeile: invalid_utf8_replaced

  • text decoded twice (ñ)

    unverändert kopiert

    Das Skript enthält genau diese Zeichen, daher werden sie kopiert; der Bericht weist auf sie hin.

    Berichtszeile: mojibake_suspected

In SQL ServerIn OracleBerichtszeile
bitNUMBER(1) mit einem CHECK auf 0 und 1Oracle 21c hat keinen booleschen Spaltentyp; 1 und 0 bewahren die Werte auf jeder Version.
char(n), varchar(n), nchar(n), nvarchar(n)VARCHAR2(n CHAR), in Zeichen gezähltLängen zählen Zeichen wie nvarchar in SQL Server.
varchar(max), nvarchar(max), text, ntextVARCHAR2(4000 CHAR), wenn jeder Wert in 4000 Bytes passt, sonst CLOBEin VARCHAR2 fasst standardmäßig 4000 Bytes, und Oracle kann kein CLOB indizieren, daher behält Text VARCHAR2, wenn seine Werte passen, und wird sonst ein CLOB.text_as_lob
empty strings and empty binary valuesNULLOracle speichert einen leeren String als NULL, daher wird ein Wert, der ' war, als NULL gelesen. Der Bericht zählt sie pro Spalte.empty_string_null
decimal(p,s), money, smallmoneyNUMBER(p,s); money als NUMBER(19,4)NUMBER fasst 38 Stellen wie decimal, daher ist jeder Wert exakt.
datetime, datetime2, smalldatetimeTIMESTAMP(p)Ein datetime ist eine Uhrzeitangabe ohne Zeitzone, wie TIMESTAMP in Oracle, das bis zu neun Nachkommastellen der Sekunde behält. date wird DATE, das auch eine Uhrzeit enthält, die auf Mitternacht bleibt.
datetimeoffsetTIMESTAMP WITH TIME ZONE, mit dem Versatz jedes WertsOracle behält Versätze von -12:00 bis +14:00; ein Wert mit einem Versatz jenseits von -12:00 wird in UTC geschrieben, derselbe Zeitpunkt.
timeINTERVAL DAY TO SECOND ab MitternachtOracle hat keinen Uhrzeittyp; ein Intervall ab Mitternacht fasst jeden Wert.
dates that aren't validNULLEin Wert, der kein Datum ist, wird NULL, und der Bericht zählt ihn.date_out_of_range
json (SQL Server 2025)CLOBDieselben JSON-Werte, die die JSON-Funktionen von Oracle lesen.
uniqueidentifierVARCHAR2(36)Dieselben Bezeichner, kleingeschrieben.
binary, varbinary, imageRAW(n) und BLOBBytes bleiben Bytes.
geometry, geographyBLOB mit den eigenen Bytes von SQL ServerSSMS schreibt räumliche Werte in der Serialisierung von SQL Server, die Byte für Byte erhalten bleibt.spatial_as_native
rowversion, timestampBLOB, leerSQL Server setzt eine Zeilenversion selbst, und SSMS schreibt keine Werte dafür.rowversion_empty
xml, sql_variant, hierarchyid, vectorVARCHAR2 oder CLOB mit dem Text jedes WertsOracle hat keinen entsprechenden Typ; xml und sql_variant behalten den Text jedes Werts und hierarchyid seinen Pfad, etwa /1/2/.type_replaced
collations that ignore case (_CI_)exakter VergleichOracle vergleicht Text exakt, sofern nicht anders angegeben, daher unterscheiden Spalten, die in SQL Server Groß-/Kleinschreibung ignorierten, jetzt Ana und ana.case_insensitive_collation
IDENTITYGENERATED BY DEFAULT ON NULL AS IDENTITY, weiter nach der höchsten IDDie kopierten IDs laden unverändert, und der Zähler macht nach der höchsten weiter.
CREATE SEQUENCECREATE SEQUENCE mit denselben OptionenSequenzen in Oracle funktionieren genauso. SSMS schreibt nicht, wie weit eine Sequenz gekommen ist, daher beginnt sie dort, wo sie angelegt wurde.
computed columnsvirtuelle SpaltenOracle berechnet generierte Spalten nur beim Lesen; PERSISTED-Spalten werden virtuell, mit denselben Werten.stored_as_virtual
computed columns with functions Oracle lackseine normale SpalteEine Formel, die sich nicht schreiben lässt, hinterlässt eine normale Spalte und eine Zeile im Bericht; SSMS schreibt keine Werte für berechnete Spalten.generated_not_translated
defaults with functions Oracle lacks, and NEXT VALUE FORkein StandardwertEin Standardwert, der sich nicht schreiben lässt, wird weggelassen und gemeldet.default_not_translated
CHECK constraintsübersetztDieselben CHECK-Bedingungen, geprüft beim Laden jeder Zeile.
CHECK constraints with functions Oracle lacksnicht angelegtEine CHECK-Bedingung, die sich nicht schreiben lässt, wird weggelassen und gemeldet.check_skipped
CHECK constraints added WITH NOCHECK or disablednicht angelegtSQL Server wendet diese CHECK-Bedingungen nicht an, daher können die Zeilen sie verletzen.check_not_enforced
filtered and columnstore indexes, and indexes on CLOB columnsnicht angelegtIntoSQL schreibt B-Tree-Indizes auf ganze Spalten; lege die anderen nach dem Laden neu an.index_skipped
foreign keysnach den Daten, ENABLE NOVALIDATE, dann validiert, mit einer Warnung bei verwaisten ZeilenDer Schlüssel prüft neue Zeilen sofort und wird zuletzt validiert; Zeilen ohne Elternzeile lassen ihn mit einer Warnung unvalidiert, statt das Laden abzubrechen.
ON UPDATE CASCADE, SET NULL or SET DEFAULT; ON DELETE SET DEFAULTentferntFremdschlüssel in Oracle handeln nur beim Löschen, mit CASCADE oder SET NULL.foreign_key_action_unsupported
names over 128 bytesgekürztNamen fassen in Oracle 12.2 und neuer 128 Bytes, in SQL Server 128 Zeichen.name_shortened
foreign keys to tables the dump doesn't createnicht angelegtEin Schlüssel kann nicht auf eine Tabelle verweisen, die es nicht gibt.foreign_key_skipped
tables on a partition schemeeine Tabelle mit den Zeilen aller PartitionenDie Zeilen sind dieselben; partitioniere die Tabelle in Oracle neu, wenn nötig.partitions_dropped
temporal tables (SYSTEM_VERSIONING)zwei Tabellen: die aktuellen Zeilen und die HistorieDie Tabelle und ihre Historientabelle werden als normale Tabellen kopiert; Oracle führt die Historie nicht selbst.system_versioning_dropped
schemasein Schema, jede Tabelle mit dem Namen ihres Schemas vorangestelltDas Skript lädt in das Schema des ausführenden Benutzers, daher bekommen Tabellen verschiedener Schemas den Namen ihres Schemas vorangestellt; Tabellen in dbo behalten ihre Namen.schemas_merged
NOT NULL columns with values that become NULLNOT NULL entferntEine Spalte, deren Werte NULL werden mussten, kann NOT NULL nicht behalten, sonst würde das Laden abbrechen.not_null_relaxed
views, functions, procedures, triggers, synonyms, types and partition functionsim Bericht aufgeführtIhr Code ist in T-SQL geschrieben, daher werden sie aufgeführt, damit du sie neu anlegst.not_converted_objects
scripts without CREATE TABLE (data only)Typen aus den Werten gelesenEin Skript nur mit Daten enthält nur Zeilen, daher kommen die Typen aus den Werten.no_schema
expressions in INSERT valuesNULLEin Konverter, der keine Datenbank ausführt, kann sie nicht auswerten.expression_value
types IntoSQL doesn't knowCLOBText nimmt jeden Wert auf; ändere den Typ nach dem Laden.unknown_type
NUL characters in texterhaltenVARCHAR2 und CLOB können ein NUL-Zeichen enthalten, daher wird der Wert unverändert kopiert.
text that isn't valid in its encodingdie fehlerhaften Bytes als ErsatzzeichenDas Skript ist UTF-8, und jeder Wert muss gültiger Text sein.invalid_utf8_replaced
text decoded twice (ñ)unverändert kopiertDas Skript enthält genau diese Zeichen, daher werden sie kopiert; der Bericht weist auf sie hin.mojibake_suspected

Das Skript in Oracle laden

Das Skript legt die Tabellen an, kopiert die Zeilen und fügt dann Schlüssel, Indizes und Fremdschlüssel hinzu, so lädt es schnell und hält beim ersten Fehler an.

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

Fremdschlüssel werden mit ENABLE NOVALIDATE hinzugefügt, sodass neue Zeilen sofort geprüft werden, und dann validiert. Verweist eine alte Zeile auf eine nicht vorhandene Zeile, nennt das Skript den Fremdschlüssel und lässt ihn unvalidiert, statt auf halbem Weg abzubrechen.

Führe bei einem großen Dump SQL*Plus auf dem Rechner der Datenbank aus. Das Skript schreibt alle 100 Zeilen fest. Der ausführende Benutzer braucht CREATE TABLE, CREATE SEQUENCE, CREATE TRIGGER und CREATE PROCEDURE sowie Quota auf seinem Tablespace.

Den SQL Server-Dump für das beste Ergebnis erstellen

Der Konverter liest, was der Dump enthält. Mit diesen Optionen bleibt mehr von deinen Daten darin:

  • Klicke in SSMS mit der rechten Maustaste auf die Datenbank, dann auf Tasks, Generate Scripts, und wähle die Tabellen. dbatools, mssql-scripter und andere Werkzeuge auf Basis derselben Bibliothek schreiben dasselbe Skript.
  • Setze unter Advanced die Option Types of data to script auf Schema and data. Ein Skript nur mit dem Schema hat Tabellen ohne Zeilen.
  • Speichere es als Unicode, den Standard von SSMS, oder als UTF-8: Beides wird gleich gelesen, und gzip funktioniert auch.

Was nicht konvertiert wird

Sichten, Funktionen, Prozeduren, Trigger, Synonyme, Regeln und Sicherheitsrichtlinien sind in T-SQL geschrieben. Sie stehen mit Namen im Bericht und werden nie stillschweigend weggelassen, damit du sie für Oracle neu schreiben kannst.

Fragen zu SQL Server zu Oracle

Keine Antwort gefunden? Schreib uns über die Kontaktseite, und ein Mensch antwortet. Kontaktseite

Wird mein Dump hochgeladen?

Nein. Der Konverter läuft in deinem Browser und liest den Dump stückweise von deiner Festplatte, daher verlässt er nie deinen Computer. Die Desktop-App und die Kommandozeile konvertieren ebenfalls auf deinem Computer.

Wie groß darf der Dump sein?

Der Konverter hält nie den ganzen Dump im Speicher: Er liest die Datei zweimal, in Abschnitten, und schreibt das Skript fortlaufend. Dumps von mehreren Gigabyte werden im Browser, in der Desktop-App und mit der Kommandozeile konvertiert.

Liest es die UTF-16-Datei, die SSMS speichert?

Ja. SSMS speichert Skripte standardmäßig als UTF-16, und der Konverter liest UTF-16 und UTF-8 gleichermaßen, gezippt oder nicht, mit GO zwischen den Batches.

Aus welchen SQL Server-Versionen kann das Skript stammen?

Skripte, die SSMS, dbatools oder mssql-scripter ab SQL Server 2017 schreiben. Jedes Test-Skript stammt aus SQL Server 2017, 2022 und 2025 und wird Zelle für Zelle mit seiner Quelle verglichen.

Bleiben IDENTITY-Werte erhalten?

Ja. IDENTITY-Spalten werden Identity-Spalten, jede Zeile behält ihre ID, und die nächste ID macht nach der höchsten weiter. Sequenzen werden mit denselben Optionen angelegt.

Was passiert mit money, datetimeoffset und anderen SQL Server-Typen?

bit wird NUMBER(1), datetime2 TIMESTAMP mit jeder Stelle, datetimeoffset TIMESTAMP WITH TIME ZONE mit seinem Versatz und nvarchar(max) CLOB, wenn seine Werte nicht in ein VARCHAR2 passen. Leere Strings werden NULL, wie Oracle sie speichert, und der Bericht zählt sie.

Was ist mit Prozeduren, Triggern und Sichten?

Sie stehen mit Namen im Bericht und werden nicht konvertiert, weil jede Datenbank sie in ihrer eigenen Sprache schreibt.

Auf welchen Oracle-Versionen lädt das Skript?

Oracle 19c und neuer. Jedes Test-Skript lädt auf 21c und 23ai und hält beim ersten Fehler an, falls etwas schiefgeht.