Oracle in SQL Server umwandeln
Leg die .sql-Datei ab, die Database Export in SQL Developer oder SQLcl schreibt, mit ihren Tabellen und Insert-Anweisungen, und lade ein SQL Server-Skript mit denselben Tabellen, Schlüsseln, Indizes und Daten herunter. Jeder Wert, den SQL Server nicht unverändert aufnehmen kann, und jedes Objekt, das es nicht übernimmt, steht im Bericht.
18 Zeilen konvertiert, 2 Korrekturen, keine abgelehnt
Tabellen in shop_2024_oracle.sqlOracle-Dump · erstellt mit SQL Developer · utf-8
customers8 Zeilen1
7 Spalten id bigint not null name nvarchar(200) not null email nvarchar(150) not null country nvarchar(2) not null is_active smallint not null signed_up datetime2(0) created_at datetime2(0) not null orders10 Zeilen1
9 Spalten id bigint not null customer_id bigint not null invoice bigint status nvarchar(10) not null total decimal(10,2) not null items int not null ordered_at datetime2(0) not null shipped_at datetime2(0) note nvarchar(510)
-- Written by IntoSQL from a Oracle dump. Load it with: sqlcmd -b -f 65001 -d <database> -i <file>
SET NOCOUNT ON;
SET ANSI_NULLS ON;
SET QUOTED_IDENTIFIER ON;
SET ANSI_PADDING ON;
SET ANSI_WARNINGS ON;
SET ARITHABORT ON;
SET CONCAT_NULL_YIELDS_NULL ON;
SET NUMERIC_ROUNDABORT OFF;
GO
CREATE SEQUENCE [dbo].[invoice_numbers] AS bigint START WITH 1020 INCREMENT BY 1 MINVALUE 1;
GO
CREATE TABLE [dbo].[customers] (
[id] bigint IDENTITY(1, 1) NOT NULL,
[name] nvarchar(200) COLLATE Latin1_General_100_BIN2 NOT NULL,
[email] nvarchar(150) COLLATE Latin1_General_100_BIN2 NOT NULL,
[country] nvarchar(2) COLLATE Latin1_General_100_BIN2 DEFAULT N'US' NOT NULL,
[is_active] smallint DEFAULT 1 NOT NULL,
[signed_up] datetime2(0) NULL,
[created_at] datetime2(0) DEFAULT SYSDATETIME() NOT NULL,
CONSTRAINT [check1] CHECK ([is_active] IN (0, 1)),
CONSTRAINT [PK_customers] PRIMARY KEY ([id])
);
GO
CREATE TABLE [dbo].[orders] (
[id] bigint IDENTITY(1, 1) NOT NULL,
[customer_id] bigint NOT NULL,
[invoice] bigint DEFAULT (NEXT VALUE FOR [dbo].[invoice_numbers]) NULL,
[status] nvarchar(10) COLLATE Latin1_General_100_BIN2 DEFAULT N'pending' NOT NULL,
[total] decimal(10,2) NOT NULL,
[items] int DEFAULT 1 NOT NULL,
[ordered_at] datetime2(0) NOT NULL,
[shipped_at] datetime2(0) NULL,
[note] nvarchar(510) COLLATE Latin1_General_100_BIN2 NULL,
CONSTRAINT [check1_2] CHECK ([status] IN (N'pending', N'paid', N'shipped', N'cancelled')),
CONSTRAINT [PK_orders] PRIMARY KEY ([id])
);
GO
SET IDENTITY_INSERT [dbo].[customers] ON;
INSERT INTO [dbo].[customers] ([id], [name], [email], [country], [is_active], [signed_up], [created_at]) VALUES
(1,N'Ana Martínez',N'ana@example.com',N'MX',1,'2023-01-15 00:00:00','2023-01-15 10:24:00.0000000');
SET IDENTITY_INSERT [dbo].[customers] OFF;
GO
SET IDENTITY_INSERT [dbo].[customers] ON;
INSERT INTO [dbo].[customers] ([id], [name], [email], [country], [is_active], [signed_up], [created_at]) VALUES
(2,N'Zoë Müller',N'zoe@example.de',N'DE',1,'2023-02-03 00:00:00','2023-02-03 08:11:42.0000000');
SET IDENTITY_INSERT [dbo].[customers] OFF;
GO
SET IDENTITY_INSERT [dbo].[customers] ON;
INSERT INTO [dbo].[customers] ([id], [name], [email], [country], [is_active], [signed_up], [created_at]) VALUES
(3,N'José Peña',N'jose@example.es',N'ES',0,'2023-03-21 00:00:00','2023-03-21 19:05:17.0000000');
SET IDENTITY_INSERT [dbo].[customers] OFF;
GO
SET IDENTITY_INSERT [dbo].[customers] ON;
INSERT INTO [dbo].[customers] ([id], [name], [email], [country], [is_active], [signed_up], [created_at]) VALUES
(4,N'李雷',N'lilei@example.cn',N'CN',1,'2023-05-09 00:00:00','2023-05-09 02:40:00.0000000');
SET IDENTITY_INSERT [dbo].[customers] OFF;
GO
SET IDENTITY_INSERT [dbo].[customers] ON;
INSERT INTO [dbo].[customers] ([id], [name], [email], [country], [is_active], [signed_up], [created_at]) VALUES
(5,N'Noah O''Brien',N'noah@example.ie',N'IE',1,NULL,'2023-06-30 14:00:00.0000000');
SET IDENTITY_INSERT [dbo].[customers] OFF;
GO
SET IDENTITY_INSERT [dbo].[customers] ON;
INSERT INTO [dbo].[customers] ([id], [name], [email], [country], [is_active], [signed_up], [created_at]) VALUES
(6,N'Amélie Laurent',N'amelie@example.fr',N'FR',1,'2024-01-02 00:00:00','2024-01-02 09:30:00.0000000');
SET IDENTITY_INSERT [dbo].[customers] OFF;
GO
SET IDENTITY_INSERT [dbo].[customers] ON;
INSERT INTO [dbo].[customers] ([id], [name], [email], [country], [is_active], [signed_up], [created_at]) VALUES
(7,N'Ravi Patel',N'ravi@example.in',N'IN',0,'2024-02-29 00:00:00','2024-02-29 23:59:59.0000000');
SET IDENTITY_INSERT [dbo].[customers] OFF;
GO
SET IDENTITY_INSERT [dbo].[customers] ON;
INSERT INTO [dbo].[customers] ([id], [name], [email], [country], [is_active], [signed_up], [created_at]) VALUES
(8,N'Sofia Rossi 🌻',N'sofia@example.it',N'IT',1,'2024-04-12 00:00:00','2024-04-12 12:12:12.0000000');
SET IDENTITY_INSERT [dbo].[customers] OFF;
GO
SET IDENTITY_INSERT [dbo].[orders] ON;
INSERT INTO [dbo].[orders] ([id], [customer_id], [invoice], [status], [total], [items], [ordered_at], [shipped_at], [note]) VALUES
(1,1,1000,N'shipped',129.9,3,'2024-03-01 10:00:00','2024-03-02 16:30:00',NULL);
SET IDENTITY_INSERT [dbo].[orders] OFF;
GO
SET IDENTITY_INSERT [dbo].[orders] ON;
INSERT INTO [dbo].[orders] ([id], [customer_id], [invoice], [status], [total], [items], [ordered_at], [shipped_at], [note]) VALUES
(2,2,1001,N'paid',54,1,'2024-03-02 11:15:00',NULL,N'Gift wrap 🎁');
SET IDENTITY_INSERT [dbo].[orders] OFF;
GO
SET IDENTITY_INSERT [dbo].[orders] ON;
INSERT INTO [dbo].[orders] ([id], [customer_id], [invoice], [status], [total], [items], [ordered_at], [shipped_at], [note]) VALUES
(3,1,1002,N'cancelled',12.5,1,'2024-03-03 09:45:00',NULL,N'Customer changed their mind');
SET IDENTITY_INSERT [dbo].[orders] OFF;
GO
SET IDENTITY_INSERT [dbo].[orders] ON;
INSERT INTO [dbo].[orders] ([id], [customer_id], [invoice], [status], [total], [items], [ordered_at], [shipped_at], [note]) VALUES
(4,4,1003,N'shipped',980,12,'2024-03-05 02:10:00','2024-03-07 08:00:00',N'请小心轻放');
SET IDENTITY_INSERT [dbo].[orders] OFF;
GO
SET IDENTITY_INSERT [dbo].[orders] ON;
INSERT INTO [dbo].[orders] ([id], [customer_id], [invoice], [status], [total], [items], [ordered_at], [shipped_at], [note]) VALUES
(5,5,1004,N'pending',45.75,2,'2024-03-08 17:20:00',NULL,N'Leave at the door; ring twice');
SET IDENTITY_INSERT [dbo].[orders] OFF;
GO
SET IDENTITY_INSERT [dbo].[orders] ON;
INSERT INTO [dbo].[orders] ([id], [customer_id], [invoice], [status], [total], [items], [ordered_at], [shipped_at], [note]) VALUES
(6,6,1005,N'shipped',310.4,5,'2024-03-10 13:00:00','2024-03-11 09:00:00',N'Fragile: "glass"');
SET IDENTITY_INSERT [dbo].[orders] OFF;
GO
SET IDENTITY_INSERT [dbo].[orders] ON;
INSERT INTO [dbo].[orders] ([id], [customer_id], [invoice], [status], [total], [items], [ordered_at], [shipped_at], [note]) VALUES
(7,8,1006,N'paid',76.2,2,'2024-03-11 18:45:00',NULL,NULL);
SET IDENTITY_INSERT [dbo].[orders] OFF;
GO
SET IDENTITY_INSERT [dbo].[orders] ON;
INSERT INTO [dbo].[orders] ([id], [customer_id], [invoice], [status], [total], [items], [ordered_at], [shipped_at], [note]) VALUES
(8,2,1007,N'paid',19.99,1,'2024-03-12 08:00:00',NULL,N'Paid at the counter');
SET IDENTITY_INSERT [dbo].[orders] OFF;
GO
SET IDENTITY_INSERT [dbo].[orders] ON;
INSERT INTO [dbo].[orders] ([id], [customer_id], [invoice], [status], [total], [items], [ordered_at], [shipped_at], [note]) VALUES
(9,3,1008,N'shipped',64,2,'2024-03-14 15:30:00',NULL,N'Shipping date never recorded');
SET IDENTITY_INSERT [dbo].[orders] OFF;
GO
SET IDENTITY_INSERT [dbo].[orders] ON;
INSERT INTO [dbo].[orders] ([id], [customer_id], [invoice], [status], [total], [items], [ordered_at], [shipped_at], [note]) VALUES
(10,7,1009,N'paid',1499,1,'2024-03-15 21:05:00',NULL,N'C:\Users\ravi\invoice.pdf');
SET IDENTITY_INSERT [dbo].[orders] OFF;
GO
-- Indexes, foreign keys, counters and triggers, after the rows.
CREATE UNIQUE INDEX [customers_email_uk] ON [dbo].[customers] ([email]);
CREATE INDEX [orders_status_date_ix] ON [dbo].[orders] ([status], [ordered_at]);
ALTER TABLE [dbo].[orders] WITH NOCHECK ADD CONSTRAINT [orders_customer_fk] FOREIGN KEY ([customer_id]) REFERENCES [dbo].[customers] ([id]);
BEGIN TRY ALTER TABLE [dbo].[orders] WITH CHECK CHECK CONSTRAINT [orders_customer_fk]; END TRY BEGIN CATCH PRINT N'Foreign key ' + N'[orders_customer_fk]' + N' has rows without a parent: it stays unchecked, and new rows are checked.'; END CATCH;
DECLARE @next decimal(38,0) = (SELECT MAX([id]) FROM [dbo].[customers]); IF @next IS NOT NULL BEGIN IF @next < 0 SET @next = 0; DBCC CHECKIDENT (N'[dbo].[customers]', RESEED, @next) WITH NO_INFOMSGS; END;
GO
EXEC sys.sp_addextendedproperty @name = N'MS_Description', @value = N'People who bought at least once', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'customers';
DECLARE @next decimal(38,0) = (SELECT MAX([id]) FROM [dbo].[orders]); IF @next IS NOT NULL BEGIN IF @next < 0 SET @next = 0; DBCC CHECKIDENT (N'[dbo].[orders]', RESEED, @next) WITH NO_INFOMSGS; END;
GO
GO
Korrekturen
- "name" von customers enthält Zeichen, die SQL Server doppelt zählt, etwa Emoji, daher ist sie nvarchar(200).
- "note" von orders enthält Zeichen, die SQL Server doppelt zählt, etwa Emoji, daher ist sie nvarchar(510).
Deine Datei wird auf diesem Computer umgewandelt und nie hochgeladen.
Weitere Beispiele:
Was sich von Oracle zu SQL Server ändert
Jede Zeile ist eine Regel, die der Konverter anwendet, mit der Berichtszeile, die er schreibt, wenn die Regel etwas an deinen Daten ändert.
BOOLEAN (23ai)
bit
SQL Server hat keine boolesche Spalte, daher sind TRUE und FALSE 1 und 0.
VARCHAR2(n BYTE|CHAR), NVARCHAR2(n), CHAR(n), NCHAR(n), CLOB, NCLOB, LONG
nvarchar(n), nchar(n) und nvarchar(max)
Längen zählen Zeichen, ob Oracle Bytes oder Zeichen gezählt hat, damit jeder Wert passt.
VARCHAR2 and NVARCHAR2 past what the target's own types hold
nvarchar(2n), oder nvarchar(max) über 4000
nvarchar zählt UTF-16-Einheiten, und ein Emoji belegt zwei, daher bekommt die Spalte Platz für jeden Wert.
Berichtszeile: text_length_widened
NUMBER, NUMBER(p,s), FLOAT(b)
decimal(p,s) oder bigint
NUMBER behält jede Stelle; ein NUMBER ohne Genauigkeit, dessen Werte alle ganze Zahlen mit bis zu 18 Stellen sind, wird eine 64-Bit-Ganzzahl, und eine negative Skalierung fasst entsprechend viele Stellen vor dem Komma.
INTERVAL YEAR TO MONTH, INTERVAL DAY TO SECOND
nvarchar(100) mit dem Text von Oracle, etwa +01-06
SQL Server hat keinen interval-Typ; der Text behält jeden Teil.
Berichtszeile: type_replaced
DATE, TIMESTAMP(p)
datetime2(p)
DATE in Oracle enthält eine Uhrzeit auf die Sekunde, daher ist es Datum und Uhrzeit. Ein Export in einer amerikanischen oder deutschen Sitzung schreibt Datumswerte ohne Uhrzeit und Jahrhundert (DD-MON-RR); exportiere in einer ISO-Sitzung (SYYYY-MM-DD HH24:MI:SS), um sie zu behalten.
TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE
datetimeoffset, mit dem Versatz jedes Werts
Derselbe Typ und dieselben Werte.
JSON (21c), and CLOB holding JSON
nvarchar(max)
Dieselben JSON-Werte; ein SQL-NULL, das der Export als 'null' geschrieben hat, bleibt NULL.
BLOB, RAW(n), LONG RAW
binary(n), varbinary(n) und varbinary(max)
Bytes bleiben Bytes.
ROWID, UROWID, XMLTYPE, SDO_GEOMETRY
nvarchar(max), und xml für XMLTYPE
Die eigenen Typen von Oracle haben keine Entsprechung; ihre Werte behalten ihren Text, ROWID-Werte eingeschlossen, auch wenn sie außerhalb von Oracle nichts bedeuten.
collations that ignore case (BINARY_CI)
dieselbe Kollation auf jeder Spalte
Spalten vergleichen und sortieren wie zuvor, und eindeutige Schlüssel halten dieselben Zeilen auseinander.
identity columns, and a sequence a BEFORE INSERT trigger assigns
IDENTITY, weiter nach der höchsten ID
Die kopierten IDs laden unverändert, und der Zähler macht nach der höchsten weiter. Eine Spalte, die ein Trigger aus einer Sequenz füllt (der Weg vor 12c), wird ebenfalls eine Identity-Spalte.
identity columns the target can't count
eine normale Ganzzahl
SQL Server zählt eine IDENTITY-Spalte pro Tabelle; jede andere behält ihre Werte ohne Zähler.
Berichtszeile: counter_dropped
CREATE SEQUENCE
CREATE SEQUENCE mit denselben Optionen
Der Export schreibt den Stand einer Sequenz als ihr START WITH, daher macht sie dort weiter.
virtual columns (GENERATED ALWAYS AS ... VIRTUAL)
berechnete Spalten
SQL Server berechnet sie aus derselben Formel; die Werte, die der Export für sie geschrieben hat, werden weggelassen.
virtual columns with functions IntoSQL doesn't write, and the || operator
eine normale Spalte
Eine Formel, die sich nicht für SQL Server schreiben lässt, hinterlässt eine normale Spalte und eine Zeile im Bericht; die Werte, die der Export für virtuelle Spalten geschrieben hat, werden weggelassen, und SQL Server kann sie nicht berechnen.
Berichtszeile: generated_not_translated
defaults with functions IntoSQL doesn't write (SYS_GUID(), ||)
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 IntoSQL doesn't write
nicht angelegt
Eine CHECK-Bedingung, die sich nicht schreiben lässt, wird weggelassen und gemeldet.
Berichtszeile: check_skipped
CHECK constraints that are DISABLE or ENABLE NOVALIDATE
nicht angelegt
Oracle wendet diese CHECK-Bedingungen nicht auf die bereits vorhandenen Zeilen an, daher können die Zeilen sie verletzen.
Berichtszeile: check_not_enforced
function-based, bitmap and domain indexes
nicht angelegt
IntoSQL schreibt B-Tree-Indizes auf ganzen Spalten; lege die anderen nach dem Laden neu an.
Berichtszeile: index_skipped
foreign keys
nach den Daten, WITH NOCHECK, dann geprüft, mit einer Warnung bei verwaisten Zeilen
Der Schlüssel wird nach den Zeilen angelegt und zuletzt geprüft; Zeilen ohne Elternzeile lassen ihn mit einer Warnung ungeprüft, statt das Laden abzubrechen.
ON DELETE CASCADE that cascades in a cycle or along a second path
NO ACTION
SQL Server lehnt Kaskaden ab, die eine Schleife bilden oder einen zweiten Weg nehmen, daher wird der Schlüssel ohne diese Aktion angelegt und der Bericht nennt sie.
Berichtszeile: foreign_key_action_dropped
foreign keys to tables the export doesn't create, and DISABLE or NOVALIDATE ones
nicht angelegt
Ein Schlüssel kann nicht auf eine Tabelle verweisen, die es nicht gibt, und einer, den Oracle nicht prüft, kann Zeilen ohne Elternzeile haben.
Berichtszeile: foreign_key_skipped
partitioned tables
eine Tabelle mit den Zeilen aller Partitionen
Die Zeilen sind dieselben; partitioniere die Tabelle in SQL Server neu, wenn nötig.
Berichtszeile: partitions_dropped
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, synonyms, types, packages, procedures, functions and other triggers
im Bericht aufgeführt
Ihr Code ist in PL/SQL geschrieben, daher werden sie aufgeführt, damit du sie neu anlegst.
Berichtszeile: not_converted_objects
exports without CREATE TABLE (data only)
Typen aus den Werten gelesen
Ein Export nur mit Daten enthält nur Zeilen, daher kommen die Typen aus den Werten.
Berichtszeile: no_schema
expressions in INSERT values other than the ones exports write
NULL
Ein Konverter, der keine Datenbank ausführt, kann sie nicht auswerten; to_date, to_timestamp, TO_CLOB, HEXTORAW und die anderen, die Exporte schreiben, werden gelesen.
Berichtszeile: expression_value
types IntoSQL doesn't know, and object types
nvarchar(max)
Text nimmt jeden Wert auf; ändere den Typ nach dem Laden.
Berichtszeile: unknown_type
dates before year 1 and time zones given as region names
NULL
Ein Wert, der kein Datum ist, wird NULL, und der Bericht zählt ihn.
Berichtszeile: date_out_of_range
NaN and Infinity in BINARY_FLOAT and BINARY_DOUBLE
NULL
Gleitkommatypen in SQL Server kennen weder NaN noch Unendlich, daher werden diese Werte NULL, und der Bericht zählt sie.
Berichtszeile: invalid_value_null
NUL characters in text
beibehalten
nvarchar kann 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 Oracle | In SQL Server | Berichtszeile |
|---|---|---|
| BOOLEAN (23ai) | bitSQL Server hat keine boolesche Spalte, daher sind TRUE und FALSE 1 und 0. | |
| VARCHAR2(n BYTE|CHAR), NVARCHAR2(n), CHAR(n), NCHAR(n), CLOB, NCLOB, LONG | nvarchar(n), nchar(n) und nvarchar(max)Längen zählen Zeichen, ob Oracle Bytes oder Zeichen gezählt hat, damit jeder Wert passt. | |
| VARCHAR2 and NVARCHAR2 past what the target's own types hold | nvarchar(2n), oder nvarchar(max) über 4000nvarchar zählt UTF-16-Einheiten, und ein Emoji belegt zwei, daher bekommt die Spalte Platz für jeden Wert. | text_length_widened |
| NUMBER, NUMBER(p,s), FLOAT(b) | decimal(p,s) oder bigintNUMBER behält jede Stelle; ein NUMBER ohne Genauigkeit, dessen Werte alle ganze Zahlen mit bis zu 18 Stellen sind, wird eine 64-Bit-Ganzzahl, und eine negative Skalierung fasst entsprechend viele Stellen vor dem Komma. | |
| INTERVAL YEAR TO MONTH, INTERVAL DAY TO SECOND | nvarchar(100) mit dem Text von Oracle, etwa +01-06SQL Server hat keinen interval-Typ; der Text behält jeden Teil. | type_replaced |
| DATE, TIMESTAMP(p) | datetime2(p)DATE in Oracle enthält eine Uhrzeit auf die Sekunde, daher ist es Datum und Uhrzeit. Ein Export in einer amerikanischen oder deutschen Sitzung schreibt Datumswerte ohne Uhrzeit und Jahrhundert (DD-MON-RR); exportiere in einer ISO-Sitzung (SYYYY-MM-DD HH24:MI:SS), um sie zu behalten. | |
| TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE | datetimeoffset, mit dem Versatz jedes WertsDerselbe Typ und dieselben Werte. | |
| JSON (21c), and CLOB holding JSON | nvarchar(max)Dieselben JSON-Werte; ein SQL-NULL, das der Export als 'null' geschrieben hat, bleibt NULL. | |
| BLOB, RAW(n), LONG RAW | binary(n), varbinary(n) und varbinary(max)Bytes bleiben Bytes. | |
| ROWID, UROWID, XMLTYPE, SDO_GEOMETRY | nvarchar(max), und xml für XMLTYPEDie eigenen Typen von Oracle haben keine Entsprechung; ihre Werte behalten ihren Text, ROWID-Werte eingeschlossen, auch wenn sie außerhalb von Oracle nichts bedeuten. | |
| collations that ignore case (BINARY_CI) | dieselbe Kollation auf jeder SpalteSpalten vergleichen und sortieren wie zuvor, und eindeutige Schlüssel halten dieselben Zeilen auseinander. | |
| identity columns, and a sequence a BEFORE INSERT trigger assigns | IDENTITY, weiter nach der höchsten IDDie kopierten IDs laden unverändert, und der Zähler macht nach der höchsten weiter. Eine Spalte, die ein Trigger aus einer Sequenz füllt (der Weg vor 12c), wird ebenfalls eine Identity-Spalte. | |
| identity columns the target can't count | eine normale GanzzahlSQL Server zählt eine IDENTITY-Spalte pro Tabelle; jede andere behält ihre Werte ohne Zähler. | counter_dropped |
| CREATE SEQUENCE | CREATE SEQUENCE mit denselben OptionenDer Export schreibt den Stand einer Sequenz als ihr START WITH, daher macht sie dort weiter. | |
| virtual columns (GENERATED ALWAYS AS ... VIRTUAL) | berechnete SpaltenSQL Server berechnet sie aus derselben Formel; die Werte, die der Export für sie geschrieben hat, werden weggelassen. | |
| virtual columns with functions IntoSQL doesn't write, and the || operator | eine normale SpalteEine Formel, die sich nicht für SQL Server schreiben lässt, hinterlässt eine normale Spalte und eine Zeile im Bericht; die Werte, die der Export für virtuelle Spalten geschrieben hat, werden weggelassen, und SQL Server kann sie nicht berechnen. | generated_not_translated |
| defaults with functions IntoSQL doesn't write (SYS_GUID(), ||) | kein 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 IntoSQL doesn't write | nicht angelegtEine CHECK-Bedingung, die sich nicht schreiben lässt, wird weggelassen und gemeldet. | check_skipped |
| CHECK constraints that are DISABLE or ENABLE NOVALIDATE | nicht angelegtOracle wendet diese CHECK-Bedingungen nicht auf die bereits vorhandenen Zeilen an, daher können die Zeilen sie verletzen. | check_not_enforced |
| function-based, bitmap and domain indexes | nicht angelegtIntoSQL schreibt B-Tree-Indizes auf ganzen Spalten; lege die anderen nach dem Laden neu an. | index_skipped |
| foreign keys | nach den Daten, WITH NOCHECK, dann geprüft, mit einer Warnung bei verwaisten ZeilenDer Schlüssel wird nach den Zeilen angelegt und zuletzt geprüft; Zeilen ohne Elternzeile lassen ihn mit einer Warnung ungeprüft, statt das Laden abzubrechen. | |
| ON DELETE CASCADE that cascades in a cycle or along a second path | NO ACTIONSQL Server lehnt Kaskaden ab, die eine Schleife bilden oder einen zweiten Weg nehmen, daher wird der Schlüssel ohne diese Aktion angelegt und der Bericht nennt sie. | foreign_key_action_dropped |
| foreign keys to tables the export doesn't create, and DISABLE or NOVALIDATE ones | nicht angelegtEin Schlüssel kann nicht auf eine Tabelle verweisen, die es nicht gibt, und einer, den Oracle nicht prüft, kann Zeilen ohne Elternzeile haben. | foreign_key_skipped |
| partitioned tables | eine Tabelle mit den Zeilen aller PartitionenDie Zeilen sind dieselben; partitioniere die Tabelle in SQL Server neu, wenn nötig. | partitions_dropped |
| NOT NULL columns with values that become NULL | NOT NULL entferntEine Spalte, deren Werte NULL werden mussten, kann NOT NULL nicht behalten, sonst würde das Laden abbrechen. | not_null_relaxed |
| views, synonyms, types, packages, procedures, functions and other triggers | im Bericht aufgeführtIhr Code ist in PL/SQL geschrieben, daher werden sie aufgeführt, damit du sie neu anlegst. | not_converted_objects |
| exports without CREATE TABLE (data only) | Typen aus den Werten gelesenEin Export nur mit Daten enthält nur Zeilen, daher kommen die Typen aus den Werten. | no_schema |
| expressions in INSERT values other than the ones exports write | NULLEin Konverter, der keine Datenbank ausführt, kann sie nicht auswerten; to_date, to_timestamp, TO_CLOB, HEXTORAW und die anderen, die Exporte schreiben, werden gelesen. | expression_value |
| types IntoSQL doesn't know, and object types | nvarchar(max)Text nimmt jeden Wert auf; ändere den Typ nach dem Laden. | unknown_type |
| dates before year 1 and time zones given as region names | NULLEin Wert, der kein Datum ist, wird NULL, und der Bericht zählt ihn. | date_out_of_range |
| NaN and Infinity in BINARY_FLOAT and BINARY_DOUBLE | NULLGleitkommatypen in SQL Server kennen weder NaN noch Unendlich, daher werden diese Werte NULL, und der Bericht zählt sie. | invalid_value_null |
| NUL characters in text | beibehaltennvarchar kann ein NUL-Zeichen enthalten, daher wird der Wert unverändert kopiert. | |
| text that isn't valid in its encoding | die 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 SQL Server 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.
sqlcmd -b -f 65001 -S localhost -d mydb -i oracle.sql_server.sqlFremdschlüssel werden mit WITH NOCHECK hinzugefügt und dann geprüft. Verweist eine Zeile auf eine nicht vorhandene Zeile, nennt das Skript den Fremdschlüssel und lässt ihn ungeprüft, statt auf halbem Weg abzubrechen.
Führe bei einem großen Dump sqlcmd auf dem Rechner des Servers aus. Jeder Stapel von bis zu 1000 Zeilen wird einzeln festgeschrieben, so bleibt das Transaktionsprotokoll klein.
Den Oracle-Dump für das beste Ergebnis erstellen
Der Konverter liest, was der Dump enthält. Mit diesen Optionen bleibt mehr von deinen Daten darin:
- Wähle in SQL Developer Tools, Database Export, mit DDL und dem Datenformat Insert. SQLcl schreibt dasselbe mit SET SQLFORMAT INSERT.
- Führe vor dem Export ALTER SESSION SET NLS_DATE_FORMAT = 'SYYYY-MM-DD HH24:MI:SS' aus: Das Standardformat schreibt Datumswerte ohne Uhrzeit und Jahrhundert.
- Eine .dmp-Datei aus exp oder expdp ist binär: Importiere sie in eine Oracle-Datenbank, zum Beispiel Oracle Database Free in Docker, und exportiere sie mit SQL Developer.
Was nicht konvertiert wird
Sichten, Pakete, Prozeduren, Funktionen, Trigger, Typen und Synonyme sind in PL/SQL geschrieben. Sie stehen mit Namen im Bericht und werden nie stillschweigend weggelassen, damit du sie für SQL Server neu schreiben kannst.
Fragen zu Oracle zu SQL Server
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.
Kann ich eine .dmp-Datei aus exp oder expdp konvertieren?
Nicht direkt: Data Pump und das ursprüngliche Export-Werkzeug schreiben ein binäres Format, das nur Oracle liest. Importiere die Datei in eine beliebige Oracle-Datenbank (Oracle Database Free läuft in Docker) und exportiere sie mit Database Export in SQL Developer oder mit SQLcl. Der Konverter weist darauf hin, wenn er eine .dmp-Datei bekommt.
Aus welchen Oracle-Versionen kann der Export stammen?
Exporte aus SQL Developer und SQLcl, mit den Tabellendefinitionen von DBMS_METADATA, ab Oracle 11g. Jeder Test-Export stammt aus Oracle 21c und 23ai, in amerikanischen, deutschen und ISO-Sitzungen, und wird Zelle für Zelle mit seiner Quelle verglichen.
Was passiert mit NUMBER, DATE und den anderen Oracle-Typen?
NUMBER wird decimal oder bei ganzen Zahlen bigint; DATE wird datetime2(0) und behält seine Uhrzeit; Text wird nvarchar, exakt verglichen wie in Oracle; CLOB nvarchar(max), BLOB varbinary(max). NaN und Infinity werden NULL, und der Bericht zählt sie.
Bleiben Identity-Spalten und Sequenzen erhalten?
Ja. Identity-Spalten werden IDENTITY-Spalten und machen nach der höchsten ID weiter; Sequenzen werden SQL Server-Sequenzen, und Standardwerte, die aus einer Sequenz ziehen, ziehen weiter aus ihr.
Was ist mit PL/SQL-Paketen, Prozeduren und Triggern?
Sie stehen mit Namen im Bericht und werden nicht konvertiert, weil jede Datenbank sie in ihrer eigenen Sprache schreibt.
Auf welchen SQL Server-Versionen lädt das Skript?
SQL Server 2017 bis 2025. Dasselbe Skript lädt auf jeder Version und hält beim ersten Fehler an, falls etwas schiefgeht.