본문으로 건너뛰기
IntoSQL 홈

Oracle에서 SQL Server로 변환

SQL Developer의 Database Export나 SQLcl이 테이블과 Insert 문을 담아 쓴 .sql 파일을 놓으면, 같은 테이블, 키, 인덱스, 데이터를 담은 SQL Server 스크립트를 다운로드할 수 있어요. SQL Server이(가) 그대로 담을 수 없는 값과 옮기지 않는 객체는 모두 보고서에 나와요.

내 파일
sqlshop_2024_oracle.sql샘플 파일, 9.3kB
내 데이터베이스

18개 행 변환, 수정 2개, 거부 없음

보기

shop_2024_oracle.sql의 테이블Oracle 덤프 · SQL Developer(으)로 작성됨 · utf-8

  • customers8개 행1
    7개 열
    idbigint not null
    namenvarchar(200) not null
    emailnvarchar(150) not null
    countrynvarchar(2) not null
    is_activesmallint not null
    signed_updatetime2(0)
    created_atdatetime2(0) not null
  • orders10개 행1
    9개 열
    idbigint not null
    customer_idbigint not null
    invoicebigint
    statusnvarchar(10) not null
    totaldecimal(10,2) not null
    itemsint not null
    ordered_atdatetime2(0) not null
    shipped_atdatetime2(0)
    notenvarchar(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

수정 사항

  1. customers의 "name" 열에 이모지처럼 SQL Server이(가) 두 개로 세는 문자가 있어 nvarchar(200)(으)로 만들었어요.
  2. orders의 "note" 열에 이모지처럼 SQL Server이(가) 두 개로 세는 문자가 있어 nvarchar(510)(으)로 만들었어요.

파일은 이 컴퓨터에서 변환되고 업로드되지 않아요.

다른 샘플:

Oracle에서 SQL Server로 바뀌는 점

각 행은 변환기가 적용하는 규칙이며, 규칙이 데이터를 바꿀 때 보고서에 쓰는 줄이 함께 나와요.

  • BOOLEAN (23ai)

    bit

    SQL Server에는 boolean 열이 없어서 TRUE와 FALSE는 1과 0이 돼요.

  • VARCHAR2(n BYTE|CHAR), NVARCHAR2(n), CHAR(n), NCHAR(n), CLOB, NCLOB, LONG

    nvarchar(n), nchar(n), nvarchar(max)

    Oracle이 바이트로 셌든 문자로 셌든 길이는 문자 수로 세므로 모든 값이 들어가요.

  • VARCHAR2 and NVARCHAR2 past what the target's own types hold

    nvarchar(2n), 4000을 넘으면 nvarchar(max)

    nvarchar는 UTF-16 단위로 세고 이모지는 두 단위를 차지하므로, 열에 모든 값이 들어갈 공간을 줘요.

    보고서 줄: text_length_widened

  • NUMBER, NUMBER(p,s), FLOAT(b)

    decimal(p,s) 또는 bigint

    NUMBER는 모든 자릿수를 유지해요. 정밀도 없는 NUMBER의 값이 모두 18자리 이하의 정수면 64비트 정수가 되고, 음수 스케일은 그만큼의 자릿수를 소수점 앞에 담아요.

  • INTERVAL YEAR TO MONTH, INTERVAL DAY TO SECOND

    +01-06 같은 Oracle의 텍스트를 담은 nvarchar(100)

    SQL Server에는 interval 타입이 없어요. 텍스트가 모든 부분을 유지해요.

    보고서 줄: type_replaced

  • DATE, TIMESTAMP(p)

    datetime2(p)

    Oracle의 DATE는 초 단위까지 시각을 담으므로 날짜와 시각이 돼요. 미국식이나 독일식 세션에서 내보내면 날짜가 시각과 세기 없이 쓰여요(DD-MON-RR). 이를 유지하려면 ISO 세션(SYYYY-MM-DD HH24:MI:SS)에서 내보내세요.

  • TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE

    datetimeoffset, 각 값의 오프셋 유지

    같은 타입과 값이에요.

  • JSON (21c), and CLOB holding JSON

    nvarchar(max)

    같은 JSON 값이에요. 내보내기가 'null'로 쓴 SQL NULL은 NULL 그대로예요.

  • BLOB, RAW(n), LONG RAW

    binary(n), varbinary(n), varbinary(max)

    바이트는 바이트 그대로 남아요.

  • ROWID, UROWID, XMLTYPE, SDO_GEOMETRY

    nvarchar(max), XMLTYPE은 xml

    Oracle 고유 타입에는 같은 타입이 없어요. 값은 텍스트를 유지하고 ROWID 값도 포함되지만, Oracle 밖에서는 의미가 없어요.

  • collations that ignore case (BINARY_CI)

    각 열에 같은 콜레이션

    열은 전과 같이 비교하고 정렬하며, 고유 키도 같은 행을 구분해요.

  • identity columns, and a sequence a BEFORE INSERT trigger assigns

    IDENTITY, 가장 큰 id 다음부터 이어짐

    복사한 id는 그대로 불러오고, 카운터는 가장 큰 id 다음부터 이어져요. 트리거가 시퀀스로 값을 채우는 열(12c 이전 방식)도 identity 열이 돼요.

  • identity columns the target can't count

    일반 정수

    SQL Server는 테이블마다 IDENTITY 열 하나만 번호를 매겨요. 다른 열은 카운터 없이 값을 유지해요.

    보고서 줄: counter_dropped

  • CREATE SEQUENCE

    같은 옵션의 CREATE SEQUENCE

    내보내기는 시퀀스가 도달한 위치를 START WITH로 쓰므로, 시퀀스는 거기서부터 이어져요.

  • virtual columns (GENERATED ALWAYS AS ... VIRTUAL)

    계산 열

    SQL Server는 같은 수식으로 계산해요. 내보내기가 이 열에 쓴 값은 제외돼요.

  • virtual columns with functions IntoSQL doesn't write, and the || operator

    일반 열

    SQL Server용으로 쓸 수 없는 수식은 일반 열로 남고 보고서에 한 줄 기록돼요. 내보내기가 가상 열에 쓴 값은 제외되고, SQL Server가 계산할 값도 없어요.

    보고서 줄: generated_not_translated

  • defaults with functions IntoSQL doesn't write (SYS_GUID(), ||)

    기본값 없음

    쓸 수 없는 기본값은 제외하고 보고해요.

    보고서 줄: default_not_translated

  • CHECK constraints

    변환됨

    같은 체크 제약이고, 각 행을 불러올 때 검사해요.

  • CHECK constraints with functions IntoSQL doesn't write

    만들지 않음

    쓸 수 없는 체크 제약은 제외하고 보고해요.

    보고서 줄: check_skipped

  • CHECK constraints that are DISABLE or ENABLE NOVALIDATE

    만들지 않음

    Oracle은 이미 있는 행에 이 체크 제약을 적용하지 않으므로 행이 이를 위반할 수 있어요.

    보고서 줄: check_not_enforced

  • function-based, bitmap and domain indexes

    만들지 않음

    IntoSQL은 열 전체에 대한 b-tree 인덱스를 써요. 다른 인덱스는 불러온 뒤 다시 만드세요.

    보고서 줄: index_skipped

  • foreign keys

    데이터 뒤에 WITH NOCHECK로 만들고, 고아 행은 경고와 함께 검사

    키는 행 다음에 만들고 마지막에 검사해요. 부모 행이 없는 행이 있으면 불러오기를 멈추지 않고 경고와 함께 검사하지 않은 상태로 남겨요.

  • ON DELETE CASCADE that cascades in a cycle or along a second path

    NO ACTION

    SQL Server는 순환하거나 두 번째 경로를 타는 연쇄 동작을 거부하므로, 키는 그 동작 없이 만들고 보고서에 적어요.

    보고서 줄: foreign_key_action_dropped

  • foreign keys to tables the export doesn't create, and DISABLE or NOVALIDATE ones

    만들지 않음

    키는 없는 테이블을 가리킬 수 없고, Oracle이 검사하지 않는 키에는 부모 행이 없는 행이 있을 수 있어요.

    보고서 줄: foreign_key_skipped

  • partitioned tables

    모든 파티션의 행을 담은 하나의 테이블

    행은 같아요. 필요하면 SQL Server에서 테이블을 다시 파티션으로 나누세요.

    보고서 줄: partitions_dropped

  • NOT NULL columns with values that become NULL

    NOT NULL 제거

    값을 NULL로 바꿔야 했던 열은 NOT NULL을 유지할 수 없어요. 유지하면 불러오기가 멈춰요.

    보고서 줄: not_null_relaxed

  • views, synonyms, types, packages, procedures, functions and other triggers

    보고서에 나열

    코드가 PL/SQL로 작성되어 있어서 직접 다시 만들 수 있도록 나열해요.

    보고서 줄: not_converted_objects

  • exports without CREATE TABLE (data only)

    값으로 판단한 타입

    데이터만 있는 내보내기에는 행만 있어서 타입을 값으로 판단해요.

    보고서 줄: no_schema

  • expressions in INSERT values other than the ones exports write

    NULL

    데이터베이스를 실행하지 않는 변환기는 이 식을 계산할 수 없어요. 내보내기가 쓰는 to_date, to_timestamp, TO_CLOB, HEXTORAW 등은 읽어요.

    보고서 줄: expression_value

  • types IntoSQL doesn't know, and object types

    nvarchar(max)

    텍스트는 어떤 값이든 담아요. 불러온 뒤 타입을 바꾸세요.

    보고서 줄: unknown_type

  • dates before year 1 and time zones given as region names

    NULL

    날짜가 아닌 값은 NULL이 되고 보고서에 개수가 나와요.

    보고서 줄: date_out_of_range

  • NaN and Infinity in BINARY_FLOAT and BINARY_DOUBLE

    NULL

    SQL Server의 부동소수점 타입에는 NaN이나 infinity가 없어서 이 값은 NULL이 되고 보고서에 개수가 나와요.

    보고서 줄: invalid_value_null

  • NUL characters in text

    유지

    nvarchar는 NUL 문자를 담을 수 있어서 값을 그대로 복사해요.

  • text that isn't valid in its encoding

    잘못된 바이트를 대체 문자로

    스크립트는 UTF-8이므로 모든 값이 올바른 텍스트여야 해요.

    보고서 줄: invalid_utf8_replaced

  • text decoded twice (ñ)

    그대로 복사

    스크립트에 정확히 이 문자들이 있으므로 그대로 복사하고, 보고서에서 알려 줘요.

    보고서 줄: mojibake_suspected

Oracle에서SQL Server에서보고서 줄
BOOLEAN (23ai)bitSQL Server에는 boolean 열이 없어서 TRUE와 FALSE는 1과 0이 돼요.
VARCHAR2(n BYTE|CHAR), NVARCHAR2(n), CHAR(n), NCHAR(n), CLOB, NCLOB, LONGnvarchar(n), nchar(n), nvarchar(max)Oracle이 바이트로 셌든 문자로 셌든 길이는 문자 수로 세므로 모든 값이 들어가요.
VARCHAR2 and NVARCHAR2 past what the target's own types holdnvarchar(2n), 4000을 넘으면 nvarchar(max)nvarchar는 UTF-16 단위로 세고 이모지는 두 단위를 차지하므로, 열에 모든 값이 들어갈 공간을 줘요.text_length_widened
NUMBER, NUMBER(p,s), FLOAT(b)decimal(p,s) 또는 bigintNUMBER는 모든 자릿수를 유지해요. 정밀도 없는 NUMBER의 값이 모두 18자리 이하의 정수면 64비트 정수가 되고, 음수 스케일은 그만큼의 자릿수를 소수점 앞에 담아요.
INTERVAL YEAR TO MONTH, INTERVAL DAY TO SECOND+01-06 같은 Oracle의 텍스트를 담은 nvarchar(100)SQL Server에는 interval 타입이 없어요. 텍스트가 모든 부분을 유지해요.type_replaced
DATE, TIMESTAMP(p)datetime2(p)Oracle의 DATE는 초 단위까지 시각을 담으므로 날짜와 시각이 돼요. 미국식이나 독일식 세션에서 내보내면 날짜가 시각과 세기 없이 쓰여요(DD-MON-RR). 이를 유지하려면 ISO 세션(SYYYY-MM-DD HH24:MI:SS)에서 내보내세요.
TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONEdatetimeoffset, 각 값의 오프셋 유지같은 타입과 값이에요.
JSON (21c), and CLOB holding JSONnvarchar(max)같은 JSON 값이에요. 내보내기가 'null'로 쓴 SQL NULL은 NULL 그대로예요.
BLOB, RAW(n), LONG RAWbinary(n), varbinary(n), varbinary(max)바이트는 바이트 그대로 남아요.
ROWID, UROWID, XMLTYPE, SDO_GEOMETRYnvarchar(max), XMLTYPE은 xmlOracle 고유 타입에는 같은 타입이 없어요. 값은 텍스트를 유지하고 ROWID 값도 포함되지만, Oracle 밖에서는 의미가 없어요.
collations that ignore case (BINARY_CI)각 열에 같은 콜레이션열은 전과 같이 비교하고 정렬하며, 고유 키도 같은 행을 구분해요.
identity columns, and a sequence a BEFORE INSERT trigger assignsIDENTITY, 가장 큰 id 다음부터 이어짐복사한 id는 그대로 불러오고, 카운터는 가장 큰 id 다음부터 이어져요. 트리거가 시퀀스로 값을 채우는 열(12c 이전 방식)도 identity 열이 돼요.
identity columns the target can't count일반 정수SQL Server는 테이블마다 IDENTITY 열 하나만 번호를 매겨요. 다른 열은 카운터 없이 값을 유지해요.counter_dropped
CREATE SEQUENCE같은 옵션의 CREATE SEQUENCE내보내기는 시퀀스가 도달한 위치를 START WITH로 쓰므로, 시퀀스는 거기서부터 이어져요.
virtual columns (GENERATED ALWAYS AS ... VIRTUAL)계산 열SQL Server는 같은 수식으로 계산해요. 내보내기가 이 열에 쓴 값은 제외돼요.
virtual columns with functions IntoSQL doesn't write, and the || operator일반 열SQL Server용으로 쓸 수 없는 수식은 일반 열로 남고 보고서에 한 줄 기록돼요. 내보내기가 가상 열에 쓴 값은 제외되고, SQL Server가 계산할 값도 없어요.generated_not_translated
defaults with functions IntoSQL doesn't write (SYS_GUID(), ||)기본값 없음쓸 수 없는 기본값은 제외하고 보고해요.default_not_translated
CHECK constraints변환됨같은 체크 제약이고, 각 행을 불러올 때 검사해요.
CHECK constraints with functions IntoSQL doesn't write만들지 않음쓸 수 없는 체크 제약은 제외하고 보고해요.check_skipped
CHECK constraints that are DISABLE or ENABLE NOVALIDATE만들지 않음Oracle은 이미 있는 행에 이 체크 제약을 적용하지 않으므로 행이 이를 위반할 수 있어요.check_not_enforced
function-based, bitmap and domain indexes만들지 않음IntoSQL은 열 전체에 대한 b-tree 인덱스를 써요. 다른 인덱스는 불러온 뒤 다시 만드세요.index_skipped
foreign keys데이터 뒤에 WITH NOCHECK로 만들고, 고아 행은 경고와 함께 검사키는 행 다음에 만들고 마지막에 검사해요. 부모 행이 없는 행이 있으면 불러오기를 멈추지 않고 경고와 함께 검사하지 않은 상태로 남겨요.
ON DELETE CASCADE that cascades in a cycle or along a second pathNO ACTIONSQL Server는 순환하거나 두 번째 경로를 타는 연쇄 동작을 거부하므로, 키는 그 동작 없이 만들고 보고서에 적어요.foreign_key_action_dropped
foreign keys to tables the export doesn't create, and DISABLE or NOVALIDATE ones만들지 않음키는 없는 테이블을 가리킬 수 없고, Oracle이 검사하지 않는 키에는 부모 행이 없는 행이 있을 수 있어요.foreign_key_skipped
partitioned tables모든 파티션의 행을 담은 하나의 테이블행은 같아요. 필요하면 SQL Server에서 테이블을 다시 파티션으로 나누세요.partitions_dropped
NOT NULL columns with values that become NULLNOT NULL 제거값을 NULL로 바꿔야 했던 열은 NOT NULL을 유지할 수 없어요. 유지하면 불러오기가 멈춰요.not_null_relaxed
views, synonyms, types, packages, procedures, functions and other triggers보고서에 나열코드가 PL/SQL로 작성되어 있어서 직접 다시 만들 수 있도록 나열해요.not_converted_objects
exports without CREATE TABLE (data only)값으로 판단한 타입데이터만 있는 내보내기에는 행만 있어서 타입을 값으로 판단해요.no_schema
expressions in INSERT values other than the ones exports writeNULL데이터베이스를 실행하지 않는 변환기는 이 식을 계산할 수 없어요. 내보내기가 쓰는 to_date, to_timestamp, TO_CLOB, HEXTORAW 등은 읽어요.expression_value
types IntoSQL doesn't know, and object typesnvarchar(max)텍스트는 어떤 값이든 담아요. 불러온 뒤 타입을 바꾸세요.unknown_type
dates before year 1 and time zones given as region namesNULL날짜가 아닌 값은 NULL이 되고 보고서에 개수가 나와요.date_out_of_range
NaN and Infinity in BINARY_FLOAT and BINARY_DOUBLENULLSQL Server의 부동소수점 타입에는 NaN이나 infinity가 없어서 이 값은 NULL이 되고 보고서에 개수가 나와요.invalid_value_null
NUL characters in text유지nvarchar는 NUL 문자를 담을 수 있어서 값을 그대로 복사해요.
text that isn't valid in its encoding잘못된 바이트를 대체 문자로스크립트는 UTF-8이므로 모든 값이 올바른 텍스트여야 해요.invalid_utf8_replaced
text decoded twice (ñ)그대로 복사스크립트에 정확히 이 문자들이 있으므로 그대로 복사하고, 보고서에서 알려 줘요.mojibake_suspected

스크립트를 SQL Server에 불러오기

스크립트는 테이블을 만들고 행을 복사한 다음 키, 인덱스, 외래 키를 추가해요. 그래서 빨리 불러오고 첫 오류에서 멈춰요.

sqlcmd -b -f 65001 -S localhost -d mydb -i oracle.sql_server.sql

외래 키는 WITH NOCHECK로 추가한 다음 검사해요. 어떤 행이 존재하지 않는 행을 가리키면, 중간에 실패하지 않고 어떤 제약인지 알려 주고 그 제약은 검사하지 않은 채로 남겨요.

큰 덤프는 서버와 같은 컴퓨터에서 sqlcmd를 실행하세요. 최대 1000행의 배치마다 따로 커밋하므로 트랜잭션 로그가 작게 유지돼요.

좋은 결과를 위한 Oracle 덤프 방법

변환기는 덤프에 담긴 내용을 읽어요. 다음 옵션을 쓰면 더 많은 데이터가 덤프에 남아요:

  • SQL Developer에서 Tools, Database Export를 고르고 DDL과 Insert 데이터 형식을 선택하세요. SQLcl은 SET SQLFORMAT INSERT로 같은 결과를 써요.
  • 내보내기 전에 ALTER SESSION SET NLS_DATE_FORMAT = 'SYYYY-MM-DD HH24:MI:SS'를 실행하세요. 기본 형식은 날짜를 시각과 세기 없이 써요.
  • exp나 expdp의 .dmp 파일은 바이너리예요. Oracle 데이터베이스(예: Docker의 Oracle Database Free)로 가져온 뒤 SQL Developer로 내보내세요.

변환되지 않는 것

뷰, 패키지, 프로시저, 함수, 트리거, 타입, 동의어는 PL/SQL로 작성돼요. 보고서에 이름으로 나열되고 몰래 빠지는 일은 없으므로, SQL Server에 맞게 다시 작성할 수 있어요.

Oracle에서 SQL Server로 변환에 관한 질문

여기에 답이 없나요? 문의 페이지로 연락하시면 담당자가 답장해요. 문의 페이지

덤프가 업로드되나요?

아니요. 변환기는 브라우저에서 실행되고 디스크의 덤프를 조각조각 읽으므로, 덤프가 컴퓨터 밖으로 나가지 않아요. 데스크톱 앱과 명령줄도 컴퓨터에서 변환해요.

덤프는 얼마나 커도 되나요?

변환기는 덤프 전체를 메모리에 올리지 않아요. 파일을 범위별로 두 번 읽고, 읽는 대로 스크립트를 써요. 수 GB 덤프도 브라우저, 데스크톱 앱, 명령줄에서 변환돼요.

exp나 expdp의 .dmp 파일을 변환할 수 있나요?

직접은 안 돼요. Data Pump와 기존 Export는 Oracle만 읽을 수 있는 바이너리 형식으로 써요. 아무 Oracle 데이터베이스(Oracle Database Free는 Docker에서 실행돼요)로 가져온 뒤 SQL Developer의 Database Export나 SQLcl로 내보내세요. 변환기는 .dmp 파일을 받으면 이를 알려 줘요.

어떤 Oracle 버전의 내보내기를 읽나요?

Oracle 11g 이상에서 SQL Developer와 SQLcl로 만든, DBMS_METADATA의 테이블 정의를 담은 내보내기예요. 모든 테스트 내보내기는 Oracle 21c와 23ai에서 미국식, 독일식, ISO 세션으로 만들고 원본과 셀 단위로 비교해요.

NUMBER, DATE 등 Oracle 타입은 어떻게 되나요?

NUMBER는 decimal이 되고, 정수는 bigint가 돼요. DATE는 시각을 유지한 채 datetime2(0)이 되고, 텍스트는 Oracle처럼 정확히 비교하는 nvarchar, CLOB은 nvarchar(max), BLOB은 varbinary(max)가 돼요. NaN과 Infinity는 NULL이 되고 보고서에 개수가 나와요.

identity 열과 시퀀스는 유지되나요?

네. identity 열은 IDENTITY 열이 되어 가장 큰 id 다음부터 이어지고, 시퀀스는 SQL Server 시퀀스가 되며, 시퀀스를 쓰는 기본값도 계속 그 시퀀스를 써요.

PL/SQL 패키지, 프로시저, 트리거는 어떻게 되나요?

데이터베이스마다 자체 언어로 작성하므로 변환하지 않고 보고서에 이름으로 나열해요.

스크립트는 어떤 SQL Server 버전에서 불러올 수 있나요?

SQL Server 2017부터 2025까지예요. 모든 버전에서 같은 스크립트를 불러올 수 있고, 문제가 생기면 첫 오류에서 멈춰요.