본문으로 건너뛰기
IntoSQL 홈

MySQL에서 Oracle로 변환

mysqldump, mariadb-dump, mysqlpump, phpMyAdmin, Adminer에서 만든 .sql 또는 .sql.gz 덤프를 놓으면, 같은 테이블, 키, 인덱스, 데이터를 담은 Oracle 스크립트를 다운로드할 수 있어요. Oracle이(가) 그대로 담을 수 없는 값과 옮기지 않는 객체는 모두 보고서에 나와요.

내 파일
sqlshop_2024.sql샘플 파일, 5.1kB
내 데이터베이스

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

보기

shop_2024.sql의 테이블MySQL 8.0.46 덤프 · mysqldump(으)로 작성됨 · utf8mb4

  • customers새 이름: CUSTOMERS8개 행2
    7개 열
    IDNUMBER(10) not null
    NAMEVARCHAR2(100 CHAR) not null
    EMAILVARCHAR2(150 CHAR) not null
    COUNTRYVARCHAR2(2 CHAR) not null
    IS_ACTIVENUMBER(1) not null
    SIGNED_UPDATE
    CREATED_ATTIMESTAMP(0) WITH TIME ZONE not null
  • orders새 이름: ORDERS10개 행2
    9개 열
    IDNUMBER(10) not null
    CUSTOMER_IDNUMBER(10) not null
    STATUSVARCHAR2(9 CHAR)
    TOTALNUMBER(10,2) not null
    ITEMSNUMBER(5) not null
    ORDERED_ATTIMESTAMP(0) not null
    SHIPPED_ATTIMESTAMP(0)
    NOTEVARCHAR2(255 CHAR)
    UPDATED_ATTIMESTAMP(0) WITH TIME ZONE not null
-- Written by IntoSQL from a MySQL 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 "CUSTOMERS" (
    "ID" NUMBER(10) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 1001),
    "NAME" VARCHAR2(100 CHAR) NOT NULL,
    "EMAIL" VARCHAR2(150 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,
    CONSTRAINT "CK_CUSTOMERS_ID" CHECK ("ID" >= 0),
    CONSTRAINT "CK_CUSTOMERS_IS_ACTIVE" CHECK ("IS_ACTIVE" IN (0, 1))
);

CREATE TABLE "ORDERS" (
    "ID" NUMBER(10) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 5001),
    "CUSTOMER_ID" NUMBER(10) NOT NULL,
    "STATUS" VARCHAR2(9 CHAR) DEFAULT 'pending',
    "TOTAL" NUMBER(10,2) NOT NULL,
    "ITEMS" NUMBER(5) DEFAULT 1 NOT NULL,
    "ORDERED_AT" TIMESTAMP(0) NOT NULL,
    "SHIPPED_AT" TIMESTAMP(0),
    "NOTE" VARCHAR2(255 CHAR),
    "UPDATED_AT" TIMESTAMP(0) WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL,
    CONSTRAINT "CK_ORDERS_ID" CHECK ("ID" >= 0),
    CONSTRAINT "CK_ORDERS_CUSTOMER_ID" CHECK ("CUSTOMER_ID" >= 0),
    CONSTRAINT "CK_ORDERS_STATUS" CHECK ("STATUS" IN ('pending', 'paid', 'shipped', 'cancelled')),
    CONSTRAINT "CK_ORDERS_ITEMS" CHECK ("ITEMS" >= 0)
);

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 10:24:00 +00:00'
);
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 08:11:42 +00:00'
);
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 19:05:17 +00:00'
);
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 02:40:00 +00:00'
);
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 14:00:00 +00:00'
);
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 09:30:00 +00:00'
);
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-02-29 23:59:59 +00:00'
);
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 12:12:12 +00:00'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
1,
1,
'shipped',
129.90,
3,
TIMESTAMP '2024-03-01 10:00:00',
TIMESTAMP '2024-03-02 16:30:00',
NULL,
TIMESTAMP '2024-03-02 16:30:00 +00:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
2,
2,
'paid',
54.00,
1,
TIMESTAMP '2024-03-02 11:15:00',
NULL,
'Gift wrap 🎁',
TIMESTAMP '2024-03-02 11:20:00 +00:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
3,
1,
'cancelled',
12.50,
1,
TIMESTAMP '2024-03-03 09:45:00',
NULL,
'Customer changed their mind',
TIMESTAMP '2024-03-03 10:00:00 +00:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
4,
4,
'shipped',
980.00,
12,
TIMESTAMP '2024-03-05 02:10:00',
TIMESTAMP '2024-03-07 08:00:00',
'请小心轻放',
TIMESTAMP '2024-03-07 08:00:00 +00:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
5,
5,
'pending',
45.75,
2,
TIMESTAMP '2024-03-08 17:20:00',
NULL,
'Leave at the door; ring twice',
TIMESTAMP '2024-03-08 17:20:00 +00:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
6,
6,
'shipped',
310.40,
5,
TIMESTAMP '2024-03-10 13:00:00',
TIMESTAMP '2024-03-11 09:00:00',
'Fragile: "glass"',
TIMESTAMP '2024-03-11 09:00:00 +00:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
7,
8,
'paid',
76.20,
2,
TIMESTAMP '2024-03-11 18:45:00',
NULL,
NULL,
TIMESTAMP '2024-03-11 18:46:00 +00:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
8,
2,
NULL,
19.99,
1,
TIMESTAMP '2024-03-12 08:00:00',
NULL,
'Status lost in an old import',
TIMESTAMP '2024-03-12 08:00:00 +00:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
9,
3,
'shipped',
64.00,
2,
TIMESTAMP '2024-03-14 15:30:00',
NULL,
'Shipping date never recorded',
TIMESTAMP '2024-03-15 10:00:00 +00:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
10,
7,
'paid',
1499.00,
1,
TIMESTAMP '2024-03-15 21:05:00',
NULL,
'C:\Users\ravi\invoice.pdf',
TIMESTAMP '2024-03-15 21:05:00 +00:00'
);
COMMIT;
END;
/

-- Keys, indexes, foreign keys, counters and triggers, after the rows.
ALTER TABLE "CUSTOMERS" ADD CONSTRAINT "PK_CUSTOMERS" PRIMARY KEY ("ID");
ALTER TABLE "CUSTOMERS" ADD CONSTRAINT "UQ_CUSTOMERS_UQ_EMAIL" UNIQUE ("EMAIL");
ALTER TABLE "ORDERS" ADD CONSTRAINT "PK_ORDERS" PRIMARY KEY ("ID");
CREATE INDEX "IX_ORDERS_IDX_CUSTOMER" ON "ORDERS" ("CUSTOMER_ID");
CREATE INDEX "IX_ORDERS_IDX_STATUS_DATE" ON "ORDERS" ("STATUS", "ORDERED_AT");
ALTER TABLE "ORDERS" ADD CONSTRAINT "FK_ORDERS_CUSTOMER" FOREIGN KEY ("CUSTOMER_ID") REFERENCES "CUSTOMERS" ("ID") ENABLE NOVALIDATE;
BEGIN
    EXECUTE IMMEDIATE 'ALTER TABLE "ORDERS" ENABLE VALIDATE CONSTRAINT "FK_ORDERS_CUSTOMER"';
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('Foreign key ' || '"FK_ORDERS_CUSTOMER"' || ' 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 "CUSTOMERS";
    IF next_id < 1001 THEN
        next_id := 1001;
    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';
DECLARE
    next_id NUMBER;
BEGIN
    SELECT NVL(MAX("ID"), 0) + 1 INTO next_id FROM "ORDERS";
    IF next_id < 5001 THEN
        next_id := 5001;
    END IF;
    EXECUTE IMMEDIATE 'ALTER TABLE "ORDERS" MODIFY ("ID" GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH ' || next_id || '))';
END;
/
CREATE OR REPLACE TRIGGER "TR_ORDERS_UPDATED_AT" BEFORE UPDATE ON "ORDERS" FOR EACH ROW
BEGIN
    IF NOT UPDATING('UPDATED_AT') THEN
        :NEW."UPDATED_AT" := SYSTIMESTAMP;
    END IF;
END;
/
DROP FUNCTION "INTOSQL_CLOB";
DROP FUNCTION "INTOSQL_BLOB";
COMMIT;
EXIT;

수정 사항

  1. customers의 "signed_up" 열은 이제 NULL을 허용해요. 일부 값을 저장할 수 없어 NULL이 됐어요.
  2. customers의 "signed_up" 열 기본값 0000‑00‑00은(는) Oracle이 받는 날짜가 아니라서 기본값을 없앴어요.
  3. orders의 "status" 열은 이제 NULL을 허용해요. 일부 값을 저장할 수 없어 NULL이 됐어요.
  4. orders의 "updated_at" 열은 업데이트할 때마다 현재 시간으로 바뀌어요. Oracle에서는 트리거가 이를 처리해요.

확인 필요

  • customers의 "signed_up" 열에 있는 1개 값은 0000‑00‑00 같은 0 날짜나 불가능한 날짜예요. Oracle이 저장할 수 없어 NULL로 두었어요. 이 날짜에 의미가 있다면 덤프하기 전에 원본에서 실제 날짜로 바꾸세요.
  • orders의 "shipped_at" 열에 있는 1개 값은 0000‑00‑00 00:00:00 같은 0 날짜나 불가능한 날짜예요. Oracle이 저장할 수 없어 NULL로 두었어요. 이 날짜에 의미가 있다면 덤프하기 전에 원본에서 실제 날짜로 바꾸세요.
  • orders의 "status" 열에 있는 1개 빈 값이 NULL이 됐어요. Oracle은(는) 빈 문자열을 NULL로 저장해요. 쿼리에서 이 열을 '와 비교한다면 대신 IS NULL로 비교하세요.

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

다른 샘플:

MySQL에서 Oracle로 바뀌는 점

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

  • TINYINT(1), BOOL

    모든 값이 0 또는 1이면 0과 1의 CHECK가 붙은 NUMBER(1), 아니면 NUMBER(3)

    MySQL의 BOOL은 -128부터 127까지 어떤 숫자든 담을 수 있는 TINYINT(1)이에요. 23ai 이전의 Oracle에는 boolean 열이 없어서 0과 1의 열은 체크 제약이 붙은 NUMBER(1)이 되고, 2나 -1을 담은 열은 숫자를 유지해요.

    보고서 줄: bool_kept_numeric

  • UNSIGNED integers

    범위를 담을 만큼 넓은 NUMBER, 음수가 아닌지 확인하는 CHECK 포함

    Oracle의 NUMBER는 MySQL의 모든 너비의 정수를 담아요. 체크 제약이 MySQL처럼 음수를 막아요.

  • ZEROFILL and display widths

    제거

    0 채움은 숫자를 표시하는 방식일 뿐 숫자의 일부가 아니에요. 숫자는 유지되며, 채움이 필요하면 읽을 때 형식을 지정하세요.

    보고서 줄: zerofill_dropped

  • FLOAT(M,D)

    BINARY_FLOAT 또는 BINARY_DOUBLE, 소수 자릿수 없이

    Oracle의 이진 부동소수점에는 고정 소수 자릿수가 없어요. 저장된 값은 그대로 복사돼요.

    보고서 줄: float_scale_dropped

  • DECIMAL(p,s)

    38자리까지는 NUMBER(p,s), 그 이상은 VARCHAR2

    Oracle의 NUMBER는 38자리까지 담아요. 더 넓은 소수는 모든 자릿수가 정확하도록 텍스트로 유지해요.

    보고서 줄: decimal_as_text

  • BIT(1), BIT(n)

    NUMBER(1), 63비트까지는 NUMBER(19), BIT(64)는 NUMBER(20)

    비트 필드는 비트가 만드는 숫자로 저장해요.

  • zero, partial or impossible dates (0000-00-00, 2024-02-30)

    NULL

    Oracle은 실제 달력 날짜만 저장해요. MySQL은 SQL 모드가 허용하면 0 날짜와 불가능한 날짜를 보관해요. 이 값은 NULL이 되고 보고서에 개수가 나와요.

    보고서 줄: invalid_date_null

  • NOT NULL columns with values that become NULL

    NOT NULL 제거

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

    보고서 줄: not_null_relaxed

  • empty strings and empty binary values

    NULL

    Oracle은 빈 문자열을 NULL로 저장하므로, '였던 값은 NULL로 읽혀요. 보고서에 열마다 개수가 나와요.

    보고서 줄: empty_string_null

  • DEFAULT '0000-00-00'

    기본값 없음

    Oracle이 저장할 수 없는 기본값은 지어낸 날짜로 바꾸지 않고 제외해요.

    보고서 줄: zero_date_default

  • TIME

    기간을 담는 INTERVAL DAY TO SECOND

    Oracle에는 하루 중 시각 타입이 없고, MySQL의 TIME은 -838:59:59부터 838:59:59까지의 기간이에요. interval은 모든 값을 담아요.

  • YEAR

    범위 CHECK가 붙은 NUMBER(4)

    Oracle에는 연도 타입이 없어요. 체크 제약이 MySQL이 허용하는 값과 같은 값만 받아요.

  • CHAR(n), VARCHAR(n)

    VARCHAR2(n CHAR), 문자 수로 셈

    길이는 MySQL처럼 문자 수로 세요. MySQL은 CHAR 값을 끝의 공백 없이 돌려주고, VARCHAR2는 그대로 유지해요.

  • VARCHAR(n) and TEXT longer than 4000 bytes

    CLOB

    VARCHAR2는 기본으로 4000바이트까지 담으므로 더 긴 텍스트는 CLOB이 돼요. 값이 모두 들어가는 열은 VARCHAR2로 남아요.

    보고서 줄: text_as_lob

  • DATETIME

    TIMESTAMP

    DATETIME은 TIMESTAMP처럼 시간대 없이 시계에 표시된 시각이에요. DATE는 Oracle의 DATE가 되며, 하루 중 시각도 담지만 자정으로 남아요.

  • TIMESTAMP

    덤프에 명시된 시간대의 TIMESTAMP WITH TIME ZONE, 명시가 없으면 UTC

    TIMESTAMP는 한 시점이에요. 덤프는 기록한 시간대를 명시해요(mysqldump는 UTC로 기록해요). 명시가 없으면 값을 UTC로 읽고 보고서에 그렇게 적어요.

    보고서 줄: timestamp_zone_assumed

  • ENUM

    값 CHECK가 붙은 VARCHAR2

    체크 제약이 있는 텍스트는 같은 값을 유지해요.

  • ENUM holding '' (MySQL's error value)

    NULL

    느슨한 SQL 모드에서 ENUM에 잘못된 값이 들어가면 MySQL은 빈 문자열을 저장해요. Oracle은 이를 NULL로 저장하고 체크 제약이 허용하며, 보고서는 다른 빈 값과 함께 개수를 세요.

  • ENUM holding values outside its list

    CHECK 없음

    목록에 없는 값은 체크 제약에 걸리므로 체크 제약을 만들지 않아요.

    보고서 줄: enum_check_skipped

  • SET

    MySQL이 쓰는 그대로의 VARCHAR2('a,b')

    Oracle에는 SET 타입이 없어요. 텍스트는 MySQL이 돌려주는 값과 같아요.

  • JSON

    CLOB

    Oracle의 JSON 함수는 모든 버전에서 텍스트에서 JSON을 읽고, CLOB은 어떤 크기의 값이든 담아요.

  • NUL bytes in text

    유지

    VARCHAR2와 CLOB은 NUL 문자를 담을 수 있어서 값을 그대로 복사해요.

  • text that isn't valid in its character set

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

    VARCHAR2로 쓰려면 텍스트를 문자로 읽어야 해요.

    보고서 줄: invalid_utf8_replaced

  • text decoded twice (ñ)

    그대로 복사

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

    보고서 줄: mojibake_suspected

  • AUTO_INCREMENT

    GENERATED BY DEFAULT ON NULL AS IDENTITY, 복사된 id 다음부터 다시 시작

    복사된 id는 그대로 불러오고, 카운터는 가장 큰 id와 덤프의 AUTO_INCREMENT 중 더 큰 값 다음부터 이어져요.

  • MyISAM AUTO_INCREMENT on the second column of a key

    테이블당 카운터 하나

    MyISAM은 키의 첫 열 그룹마다 따로 세지만, Oracle은 테이블마다 카운터가 하나예요.

    보고서 줄: myisam_group_autoincrement

  • ON UPDATE CURRENT_TIMESTAMP

    BEFORE UPDATE 트리거

    업데이트에서 열을 지정하지 않으면 트리거가 열을 현재 시간으로 설정해요.

    보고서 줄: on_update_trigger

  • generated columns

    가상 열

    Oracle은 생성 열을 읽을 때만 계산해요. STORED 열은 같은 값을 가진 가상 열이 돼요.

    보고서 줄: stored_as_virtual

  • generated columns with functions Oracle lacks

    일반 열

    Oracle용으로 쓸 수 없는 수식은 일반 열로 남고 보고서에 한 줄 기록돼요.

    보고서 줄: generated_not_translated

  • INVISIBLE columns

    INVISIBLE 열

    Oracle은 MySQL처럼 SELECT *에서 보이지 않는 열을 숨겨요.

  • CHECK constraints

    변환해서 CREATE TABLE 안에 인라인으로

    인라인 체크 제약은 각 행을 불러올 때 검사해요.

  • CHECK constraints with functions Oracle lacks

    만들지 않음

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

    보고서 줄: check_skipped

  • CHECK ... NOT ENFORCED

    만들지 않음

    MySQL은 이 체크 제약을 적용하지 않고 보관만 하므로, 행이 제약을 어길 수 있어요.

    보고서 줄: check_not_enforced

  • defaults with functions Oracle lacks

    기본값 없음

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

    보고서 줄: default_not_translated

  • keys and indexes on a prefix, c(20)

    열의 SUBSTR에 대한 인덱스

    열의 같은 앞부분에 대한 함수 인덱스가 같은 행을 구분하고, Oracle이 통째로 인덱싱할 수 없는 CLOB 열도 인덱싱해요.

    보고서 줄: prefix_unique

  • FULLTEXT indexes

    만들지 않음

    Oracle Text는 자체 인덱스 타입과 쿼리로 전문 검색을 구성해요.

    보고서 줄: fulltext_not_created

  • SPATIAL indexes

    만들지 않음

    지오메트리는 WKB 바이트로 저장되는데, 공간 인덱스는 이를 읽을 수 없어요.

    보고서 줄: spatial_index_not_created

  • functional indexes, and indexes on whole CLOB or BLOB columns

    만들지 않음

    Oracle은 대형 객체를 통째로 인덱싱할 수 없고, 일부 MySQL 함수에는 Oracle에 해당하는 함수가 없어요.

    보고서 줄: index_skipped

  • foreign keys

    데이터 뒤에 ENABLE NOVALIDATE로 만들고, 고아 행은 경고와 함께 검증

    덤프는 FOREIGN_KEY_CHECKS=0으로 불러오고 MyISAM은 전혀 확인하지 않으므로, 부모 없는 행이 흔해요. 키는 새 행을 바로 검사하고 마지막에 검증돼요. 고아 행이 있으면 불러오기를 멈추지 않고 경고와 함께 검증하지 않은 채로 남겨요.

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

    제거

    Oracle의 외래 키는 삭제할 때만, CASCADE 또는 SET NULL로 동작해요.

    보고서 줄: foreign_key_action_unsupported

  • foreign keys to columns without a unique key

    만들지 않음

    Oracle은 참조되는 열에 기본 키나 고유 제약이 필요하지만 InnoDB는 그렇지 않아요.

    보고서 줄: foreign_key_skipped

  • table and column names

    일반 이름이면 대문자, 아니면 쓴 그대로

    Oracle은 따옴표 없이 쓴 이름을 대문자로 저장해요. 그래서 일반 이름은 대문자가 되어 쿼리에서 따옴표를 생략할 수 있고, 다른 이름은 대소문자를 유지하며 따옴표가 필요해요.

    보고서 줄: identifier_renamed

  • names over 128 bytes

    줄임

    Oracle 12.2 이상의 이름은 128바이트까지예요.

    보고서 줄: name_shortened

  • GEOMETRY, POINT, POLYGON...

    WKB를 담은 BLOB

    WKB는 모든 공간 라이브러리가 읽는 표준 형식이에요. SDO_GEOMETRY에는 Oracle Spatial의 메타데이터가 필요해요.

    보고서 줄: geometry_as_blob

  • INET4, INET6, UUID (MariaDB)

    VARCHAR2(39), VARCHAR2(36)

    Oracle에는 두 타입 모두 없어요. 텍스트는 MariaDB가 돌려주는 값과 같아요.

  • BINARY, VARBINARY, BLOB

    2000바이트까지는 RAW, 아니면 BLOB

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

  • PARTITION BY

    하나의 테이블

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

    보고서 줄: partitions_dropped

  • WITH SYSTEM VERSIONING (MariaDB)

    현재 행만 담은 테이블

    덤프에는 현재 행만 들어 있어요.

    보고서 줄: system_versioning_dropped

  • MyISAM, MEMORY and other engines

    일반 테이블

    Oracle의 테이블 엔진은 하나예요.

    보고서 줄: engine_dropped

  • views, triggers, procedures, functions and events

    보고서에 나열

    이 객체들의 코드는 MySQL 언어로 작성되어 있어서, 직접 다시 만들 수 있도록 나열해요.

    보고서 줄: not_converted_objects

  • dumps without CREATE TABLE

    값으로 판단한 타입

    --no-create-info로 만든 덤프에는 행만 있어서 타입을 값으로 판단해요.

    보고서 줄: no_schema

  • geometries in a dump without CREATE TABLE

    WKB를 담은 BLOB

    MySQL의 지오메트리 형식을 값에서 알아보고 표준 WKB로 저장해요.

    보고서 줄: geometry_inferred

  • _ci collations

    정확한 비교

    Oracle은 따로 지정하지 않으면 텍스트를 정확히 비교해요.

    보고서 줄: case_insensitive_collation

  • SET NAMES utf8 from utf8mb4 tables

    변환하고 경고 표시

    MySQL 5.x의 mysqldump는 기본으로 3바이트 utf8을 쓰고, 변환기가 파일을 보기 전에 모든 이모지를 물음표로 바꿔요.

    보고서 줄: dump_lost_four_byte_chars

  • dumps without SET NAMES whose text isn't UTF-8

    Latin-1 (Windows-1252)로 읽음

    MySQL의 latin1은 Windows-1252이며, 이런 덤프에서 흔히 쓰는 인코딩이에요.

    보고서 줄: charset_guessed

  • sjis, cp932, gbk, big5 dumps

    UTF-8로 읽고 경고 표시

    이 인코딩은 아직 디코딩하지 않아요.

    보고서 줄: unsupported_charset

  • UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows

    계산함

    일부 덤프 도구는 값을 이런 함수 호출로 써요. 호출이 만드는 값으로 읽고, 지리 WKT는 경도가 먼저 오도록 바꿔요.

  • other expressions in rows

    NULL

    데이터베이스를 실행하지 않는 변환기는 이 식을 계산할 수 없어요.

    보고서 줄: expression_value

  • DEFAULT in VALUES

    열의 기본값

    리터럴 기본값을 행에 복사해요.

    보고서 줄: default_keyword_filled

  • DEFAULT in VALUES without a literal default

    NULL

    복사할 값이 없어요.

    보고서 줄: default_keyword_null

  • REPLACE and INSERT IGNORE

    일반 행

    덤프에는 키마다 행이 하나라서 행은 같아요.

    보고서 줄: replace_as_insert

  • types IntoSQL doesn't know

    CLOB

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

    보고서 줄: unknown_type

  • values that don't fit their column

    NULL

    손상되었거나 직접 작성한 덤프에는 열이 담을 수 없는 값이 있을 수 있어요. 나머지를 불러올 수 있도록 이 값은 NULL이 돼요.

    보고서 줄: invalid_value_null

  • unreadable geometries

    NULL

    지오메트리가 아닌 바이트는 지오메트리로 저장할 수 없어요.

    보고서 줄: bad_geometry

  • dumps of several databases

    하나의 스키마, 각 테이블 이름 앞에 데이터베이스 이름

    스크립트는 실행하는 사용자의 스키마로 불러오므로, 다른 데이터베이스의 테이블 이름 앞에는 해당 데이터베이스 이름이 붙어요.

    보고서 줄: databases_merged

  • CREATE SEQUENCE (MariaDB)

    도달한 값부터 시작하는 CREATE SEQUENCE

    Oracle 시퀀스도 같은 방식으로 작동해요.

  • VECTOR(n) (MariaDB 11.7+)

    부동소수점 값을 JSON 배열로 담은 CLOB

    vector 타입은 Oracle 23ai에만 있어요. JSON 배열은 모든 버전에서 모든 부동소수점 값을 유지해요.

    보고서 줄: type_replaced

MySQL에서Oracle에서보고서 줄
TINYINT(1), BOOL모든 값이 0 또는 1이면 0과 1의 CHECK가 붙은 NUMBER(1), 아니면 NUMBER(3)MySQL의 BOOL은 -128부터 127까지 어떤 숫자든 담을 수 있는 TINYINT(1)이에요. 23ai 이전의 Oracle에는 boolean 열이 없어서 0과 1의 열은 체크 제약이 붙은 NUMBER(1)이 되고, 2나 -1을 담은 열은 숫자를 유지해요.bool_kept_numeric
UNSIGNED integers범위를 담을 만큼 넓은 NUMBER, 음수가 아닌지 확인하는 CHECK 포함Oracle의 NUMBER는 MySQL의 모든 너비의 정수를 담아요. 체크 제약이 MySQL처럼 음수를 막아요.
ZEROFILL and display widths제거0 채움은 숫자를 표시하는 방식일 뿐 숫자의 일부가 아니에요. 숫자는 유지되며, 채움이 필요하면 읽을 때 형식을 지정하세요.zerofill_dropped
FLOAT(M,D)BINARY_FLOAT 또는 BINARY_DOUBLE, 소수 자릿수 없이Oracle의 이진 부동소수점에는 고정 소수 자릿수가 없어요. 저장된 값은 그대로 복사돼요.float_scale_dropped
DECIMAL(p,s)38자리까지는 NUMBER(p,s), 그 이상은 VARCHAR2Oracle의 NUMBER는 38자리까지 담아요. 더 넓은 소수는 모든 자릿수가 정확하도록 텍스트로 유지해요.decimal_as_text
BIT(1), BIT(n)NUMBER(1), 63비트까지는 NUMBER(19), BIT(64)는 NUMBER(20)비트 필드는 비트가 만드는 숫자로 저장해요.
zero, partial or impossible dates (0000-00-00, 2024-02-30)NULLOracle은 실제 달력 날짜만 저장해요. MySQL은 SQL 모드가 허용하면 0 날짜와 불가능한 날짜를 보관해요. 이 값은 NULL이 되고 보고서에 개수가 나와요.invalid_date_null
NOT NULL columns with values that become NULLNOT NULL 제거빈 문자열을 포함해 값을 NULL로 바꿔야 했던 열은 NOT NULL을 유지할 수 없어요. 유지하면 불러오기가 멈춰요.not_null_relaxed
empty strings and empty binary valuesNULLOracle은 빈 문자열을 NULL로 저장하므로, '였던 값은 NULL로 읽혀요. 보고서에 열마다 개수가 나와요.empty_string_null
DEFAULT '0000-00-00'기본값 없음Oracle이 저장할 수 없는 기본값은 지어낸 날짜로 바꾸지 않고 제외해요.zero_date_default
TIME기간을 담는 INTERVAL DAY TO SECONDOracle에는 하루 중 시각 타입이 없고, MySQL의 TIME은 -838:59:59부터 838:59:59까지의 기간이에요. interval은 모든 값을 담아요.
YEAR범위 CHECK가 붙은 NUMBER(4)Oracle에는 연도 타입이 없어요. 체크 제약이 MySQL이 허용하는 값과 같은 값만 받아요.
CHAR(n), VARCHAR(n)VARCHAR2(n CHAR), 문자 수로 셈길이는 MySQL처럼 문자 수로 세요. MySQL은 CHAR 값을 끝의 공백 없이 돌려주고, VARCHAR2는 그대로 유지해요.
VARCHAR(n) and TEXT longer than 4000 bytesCLOBVARCHAR2는 기본으로 4000바이트까지 담으므로 더 긴 텍스트는 CLOB이 돼요. 값이 모두 들어가는 열은 VARCHAR2로 남아요.text_as_lob
DATETIMETIMESTAMPDATETIME은 TIMESTAMP처럼 시간대 없이 시계에 표시된 시각이에요. DATE는 Oracle의 DATE가 되며, 하루 중 시각도 담지만 자정으로 남아요.
TIMESTAMP덤프에 명시된 시간대의 TIMESTAMP WITH TIME ZONE, 명시가 없으면 UTCTIMESTAMP는 한 시점이에요. 덤프는 기록한 시간대를 명시해요(mysqldump는 UTC로 기록해요). 명시가 없으면 값을 UTC로 읽고 보고서에 그렇게 적어요.timestamp_zone_assumed
ENUM값 CHECK가 붙은 VARCHAR2체크 제약이 있는 텍스트는 같은 값을 유지해요.
ENUM holding '' (MySQL's error value)NULL느슨한 SQL 모드에서 ENUM에 잘못된 값이 들어가면 MySQL은 빈 문자열을 저장해요. Oracle은 이를 NULL로 저장하고 체크 제약이 허용하며, 보고서는 다른 빈 값과 함께 개수를 세요.
ENUM holding values outside its listCHECK 없음목록에 없는 값은 체크 제약에 걸리므로 체크 제약을 만들지 않아요.enum_check_skipped
SETMySQL이 쓰는 그대로의 VARCHAR2('a,b')Oracle에는 SET 타입이 없어요. 텍스트는 MySQL이 돌려주는 값과 같아요.
JSONCLOBOracle의 JSON 함수는 모든 버전에서 텍스트에서 JSON을 읽고, CLOB은 어떤 크기의 값이든 담아요.
NUL bytes in text유지VARCHAR2와 CLOB은 NUL 문자를 담을 수 있어서 값을 그대로 복사해요.
text that isn't valid in its character set잘못된 바이트를 대체 문자로VARCHAR2로 쓰려면 텍스트를 문자로 읽어야 해요.invalid_utf8_replaced
text decoded twice (ñ)그대로 복사덤프에 정확히 이 문자들이 있으므로 그대로 복사하고, 보고서에서 알려 줘요.mojibake_suspected
AUTO_INCREMENTGENERATED BY DEFAULT ON NULL AS IDENTITY, 복사된 id 다음부터 다시 시작복사된 id는 그대로 불러오고, 카운터는 가장 큰 id와 덤프의 AUTO_INCREMENT 중 더 큰 값 다음부터 이어져요.
MyISAM AUTO_INCREMENT on the second column of a key테이블당 카운터 하나MyISAM은 키의 첫 열 그룹마다 따로 세지만, Oracle은 테이블마다 카운터가 하나예요.myisam_group_autoincrement
ON UPDATE CURRENT_TIMESTAMPBEFORE UPDATE 트리거업데이트에서 열을 지정하지 않으면 트리거가 열을 현재 시간으로 설정해요.on_update_trigger
generated columns가상 열Oracle은 생성 열을 읽을 때만 계산해요. STORED 열은 같은 값을 가진 가상 열이 돼요.stored_as_virtual
generated columns with functions Oracle lacks일반 열Oracle용으로 쓸 수 없는 수식은 일반 열로 남고 보고서에 한 줄 기록돼요.generated_not_translated
INVISIBLE columnsINVISIBLE 열Oracle은 MySQL처럼 SELECT *에서 보이지 않는 열을 숨겨요.
CHECK constraints변환해서 CREATE TABLE 안에 인라인으로인라인 체크 제약은 각 행을 불러올 때 검사해요.
CHECK constraints with functions Oracle lacks만들지 않음Oracle용으로 쓸 수 없는 체크 제약은 제외하고 보고해요.check_skipped
CHECK ... NOT ENFORCED만들지 않음MySQL은 이 체크 제약을 적용하지 않고 보관만 하므로, 행이 제약을 어길 수 있어요.check_not_enforced
defaults with functions Oracle lacks기본값 없음Oracle용으로 쓸 수 없는 기본값은 제외하고 보고해요.default_not_translated
keys and indexes on a prefix, c(20)열의 SUBSTR에 대한 인덱스열의 같은 앞부분에 대한 함수 인덱스가 같은 행을 구분하고, Oracle이 통째로 인덱싱할 수 없는 CLOB 열도 인덱싱해요.prefix_unique
FULLTEXT indexes만들지 않음Oracle Text는 자체 인덱스 타입과 쿼리로 전문 검색을 구성해요.fulltext_not_created
SPATIAL indexes만들지 않음지오메트리는 WKB 바이트로 저장되는데, 공간 인덱스는 이를 읽을 수 없어요.spatial_index_not_created
functional indexes, and indexes on whole CLOB or BLOB columns만들지 않음Oracle은 대형 객체를 통째로 인덱싱할 수 없고, 일부 MySQL 함수에는 Oracle에 해당하는 함수가 없어요.index_skipped
foreign keys데이터 뒤에 ENABLE NOVALIDATE로 만들고, 고아 행은 경고와 함께 검증덤프는 FOREIGN_KEY_CHECKS=0으로 불러오고 MyISAM은 전혀 확인하지 않으므로, 부모 없는 행이 흔해요. 키는 새 행을 바로 검사하고 마지막에 검증돼요. 고아 행이 있으면 불러오기를 멈추지 않고 경고와 함께 검증하지 않은 채로 남겨요.
ON UPDATE CASCADE, SET NULL or SET DEFAULT; ON DELETE SET DEFAULT제거Oracle의 외래 키는 삭제할 때만, CASCADE 또는 SET NULL로 동작해요.foreign_key_action_unsupported
foreign keys to columns without a unique key만들지 않음Oracle은 참조되는 열에 기본 키나 고유 제약이 필요하지만 InnoDB는 그렇지 않아요.foreign_key_skipped
table and column names일반 이름이면 대문자, 아니면 쓴 그대로Oracle은 따옴표 없이 쓴 이름을 대문자로 저장해요. 그래서 일반 이름은 대문자가 되어 쿼리에서 따옴표를 생략할 수 있고, 다른 이름은 대소문자를 유지하며 따옴표가 필요해요.identifier_renamed
names over 128 bytes줄임Oracle 12.2 이상의 이름은 128바이트까지예요.name_shortened
GEOMETRY, POINT, POLYGON...WKB를 담은 BLOBWKB는 모든 공간 라이브러리가 읽는 표준 형식이에요. SDO_GEOMETRY에는 Oracle Spatial의 메타데이터가 필요해요.geometry_as_blob
INET4, INET6, UUID (MariaDB)VARCHAR2(39), VARCHAR2(36)Oracle에는 두 타입 모두 없어요. 텍스트는 MariaDB가 돌려주는 값과 같아요.
BINARY, VARBINARY, BLOB2000바이트까지는 RAW, 아니면 BLOB바이트는 바이트 그대로 남아요.
PARTITION BY하나의 테이블행은 같아요. 필요하면 Oracle에서 테이블을 다시 파티션으로 나누세요.partitions_dropped
WITH SYSTEM VERSIONING (MariaDB)현재 행만 담은 테이블덤프에는 현재 행만 들어 있어요.system_versioning_dropped
MyISAM, MEMORY and other engines일반 테이블Oracle의 테이블 엔진은 하나예요.engine_dropped
views, triggers, procedures, functions and events보고서에 나열이 객체들의 코드는 MySQL 언어로 작성되어 있어서, 직접 다시 만들 수 있도록 나열해요.not_converted_objects
dumps without CREATE TABLE값으로 판단한 타입--no-create-info로 만든 덤프에는 행만 있어서 타입을 값으로 판단해요.no_schema
geometries in a dump without CREATE TABLEWKB를 담은 BLOBMySQL의 지오메트리 형식을 값에서 알아보고 표준 WKB로 저장해요.geometry_inferred
_ci collations정확한 비교Oracle은 따로 지정하지 않으면 텍스트를 정확히 비교해요.case_insensitive_collation
SET NAMES utf8 from utf8mb4 tables변환하고 경고 표시MySQL 5.x의 mysqldump는 기본으로 3바이트 utf8을 쓰고, 변환기가 파일을 보기 전에 모든 이모지를 물음표로 바꿔요.dump_lost_four_byte_chars
dumps without SET NAMES whose text isn't UTF-8Latin-1 (Windows-1252)로 읽음MySQL의 latin1은 Windows-1252이며, 이런 덤프에서 흔히 쓰는 인코딩이에요.charset_guessed
sjis, cp932, gbk, big5 dumpsUTF-8로 읽고 경고 표시이 인코딩은 아직 디코딩하지 않아요.unsupported_charset
UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows계산함일부 덤프 도구는 값을 이런 함수 호출로 써요. 호출이 만드는 값으로 읽고, 지리 WKT는 경도가 먼저 오도록 바꿔요.
other expressions in rowsNULL데이터베이스를 실행하지 않는 변환기는 이 식을 계산할 수 없어요.expression_value
DEFAULT in VALUES열의 기본값리터럴 기본값을 행에 복사해요.default_keyword_filled
DEFAULT in VALUES without a literal defaultNULL복사할 값이 없어요.default_keyword_null
REPLACE and INSERT IGNORE일반 행덤프에는 키마다 행이 하나라서 행은 같아요.replace_as_insert
types IntoSQL doesn't knowCLOB텍스트는 어떤 값이든 담아요. 불러온 뒤 타입을 바꾸세요.unknown_type
values that don't fit their columnNULL손상되었거나 직접 작성한 덤프에는 열이 담을 수 없는 값이 있을 수 있어요. 나머지를 불러올 수 있도록 이 값은 NULL이 돼요.invalid_value_null
unreadable geometriesNULL지오메트리가 아닌 바이트는 지오메트리로 저장할 수 없어요.bad_geometry
dumps of several databases하나의 스키마, 각 테이블 이름 앞에 데이터베이스 이름스크립트는 실행하는 사용자의 스키마로 불러오므로, 다른 데이터베이스의 테이블 이름 앞에는 해당 데이터베이스 이름이 붙어요.databases_merged
CREATE SEQUENCE (MariaDB)도달한 값부터 시작하는 CREATE SEQUENCEOracle 시퀀스도 같은 방식으로 작동해요.
VECTOR(n) (MariaDB 11.7+)부동소수점 값을 JSON 배열로 담은 CLOBvector 타입은 Oracle 23ai에만 있어요. JSON 배열은 모든 버전에서 모든 부동소수점 값을 유지해요.type_replaced

스크립트를 Oracle에 불러오기

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

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

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

큰 덤프는 데이터베이스와 같은 컴퓨터에서 SQL*Plus를 실행하세요. 스크립트는 100행마다 커밋해요. 실행하는 사용자에게는 CREATE TABLE, CREATE SEQUENCE, CREATE TRIGGER, CREATE PROCEDURE 권한과 테이블스페이스 할당량이 필요해요.

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

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

  • --default-character-set=utf8mb4는 이모지와 기타 4바이트 문자를 유지해요. utf8 덤프는 변환기가 보기 전에 이 문자를 잃어요.
  • --hex-blob은 바이너리 열을 16진수로 써서, 시스템 간에 복사해도 손상되지 않아요.
  • --routines --triggers --events는 이 객체들을 덤프에 추가해서 보고서에 나열할 수 있게 해요.

변환되지 않는 것

뷰, 트리거, 저장 프로시저, 함수, 이벤트는 데이터베이스마다 자체 언어로 작성돼요. 보고서에 이름으로 나열되고 몰래 빠지는 일은 없으므로, Oracle에 맞게 다시 작성할 수 있어요.

MySQL에서 Oracle로 변환에 관한 질문

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

덤프가 업로드되나요?

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

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

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

MariaDB 덤프도 읽나요?

네. mariadb-dump와 MariaDB 10.3부터 12까지의 덤프도 같은 방식으로 변환되며, MariaDB의 INET6, INET4, UUID 열도 포함돼요.

0000-00-00 날짜는 어떻게 되나요?

Oracle에는 0 날짜가 없어서 NULL이 되고, 열은 NULL을 허용하게 돼요. 열마다 몇 개였는지 보고서에 나와요. 빈 문자열도 Oracle이(가) 저장하는 방식대로 NULL이 돼요.

AUTO_INCREMENT 값은 유지되나요?

네. 각 AUTO_INCREMENT 열은 identity 열이 되고, 모든 행은 id를 유지해요. 다음 id는 가장 큰 id 다음부터 이어지고, 테이블의 AUTO_INCREMENT가 더 크면 그 다음부터 이어져요.

TINYINT(1)은 boolean이 되나요?

23ai 이전의 Oracle에는 boolean 열이 없어요. 값이 모두 0 또는 1인 열은 그 값만 받는 체크 제약이 붙은 NUMBER(1)이 되고, 다른 숫자가 있는 열은 그 값을 유지하며 보고서에 이유가 나와요.

저장 프로시저와 트리거는 어떻게 되나요?

데이터베이스마다 자체 언어로 작성하므로 변환하지 않고 보고서에 이름으로 나열해요. 예외는 ON UPDATE CURRENT_TIMESTAMP로, Oracle 트리거가 돼요.

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

Oracle 19c 이상이에요. 모든 테스트 덤프를 21c와 23ai에서 불러오며, 문제가 생기면 첫 오류에서 멈춰요.