本文へスキップ
IntoSQL ホーム

SQLite を Oracle に変換

SQLite データベースファイル (.db、.sqlite、.sqlite3) または sqlite3 の .dump が書き出す SQL をドロップすると、同じテーブル、キー、インデックス、データを持つ Oracle スクリプトをダウンロードできます。各列には値が収まる型を付け、Oracle がそのまま保持できない値はすべてレポートに記載されます。

ファイル
sqlshop_2024_sqlite.sqlサンプルファイル、3.4 KB
データベース

18 行を変換、修正なし、却下なし

表示

shop_2024_sqlite.sql のテーブルSQLite のダンプ · sqlite3 で作成 · utf-8

  • customersCUSTOMERS として書き出し8 行
    7 列
    IDNUMBER(19) not null
    NAMEVARCHAR2(4000 CHAR) not null
    EMAILVARCHAR2(750 CHAR) not null
    COUNTRYVARCHAR2(4000 CHAR) not null
    IS_ACTIVENUMBER(1) not null
    SIGNED_UPDATE
    CREATED_ATTIMESTAMP(0) not null
  • ordersORDERS として書き出し10 行
    9 列
    IDNUMBER(19) not null
    CUSTOMER_IDNUMBER(19) not null
    STATUSVARCHAR2(750 CHAR) not null
    TOTALNUMBER(10,2) not null
    ITEMSNUMBER(10) not null
    ORDERED_ATTIMESTAMP(0) not null
    SHIPPED_ATTIMESTAMP(0)
    NOTEVARCHAR2(4000 CHAR)
    RECEIPTBLOB

未変換

  • ビュー order_totals
  • トリガー orders_shipped

これらはデータベースごとに独自の言語で書かれます。Oracle 用に書き直してください。

-- Written by IntoSQL from a SQLite 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(19) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 9),
    "NAME" VARCHAR2(4000 CHAR) NOT NULL,
    "EMAIL" VARCHAR2(750 CHAR) NOT NULL,
    "COUNTRY" VARCHAR2(4000 CHAR) DEFAULT 'US' NOT NULL,
    "IS_ACTIVE" NUMBER(1) DEFAULT 1 NOT NULL,
    "SIGNED_UP" DATE,
    "CREATED_AT" TIMESTAMP(0) DEFAULT LOCALTIMESTAMP NOT NULL,
    CONSTRAINT "CK_CUSTOMERS_IS_ACTIVE" CHECK ("IS_ACTIVE" IN (0, 1)),
    CONSTRAINT "CHECK1" CHECK (LENGTH("COUNTRY") = 2)
);

CREATE TABLE "ORDERS" (
    "ID" NUMBER(19) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 11),
    "CUSTOMER_ID" NUMBER(19) NOT NULL,
    "STATUS" VARCHAR2(750 CHAR) DEFAULT 'pending' NOT NULL,
    "TOTAL" NUMBER(10,2) NOT NULL,
    "ITEMS" NUMBER(10) DEFAULT 1 NOT NULL,
    "ORDERED_AT" TIMESTAMP(0) NOT NULL,
    "SHIPPED_AT" TIMESTAMP(0),
    "NOTE" VARCHAR2(4000 CHAR),
    "RECEIPT" BLOB,
    CONSTRAINT "CHECK1_2" CHECK ("STATUS" IN ('pending', 'paid', 'shipped', 'cancelled'))
);

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'
);
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 08:11:42'
);
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 19:05:17'
);
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 02:40: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 14:00: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 09:30: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-02-29 23:59:59'
);
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 12:12:12'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
1,
1,
'shipped',
129.9,
3,
TIMESTAMP '2024-03-01 10:00:00',
TIMESTAMP '2024-03-02 16:30:00',
NULL,
NULL
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
2,
2,
'paid',
54,
1,
TIMESTAMP '2024-03-02 11:15:00',
NULL,
'Gift wrap 🎁',
NULL
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
3,
1,
'cancelled',
12.5,
1,
TIMESTAMP '2024-03-03 09:45:00',
NULL,
'Customer changed their mind',
NULL
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
4,
4,
'shipped',
980,
12,
TIMESTAMP '2024-03-05 02:10:00',
TIMESTAMP '2024-03-07 08:00:00',
'请小心轻放',
HEXTORAW('25504446')
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
5,
5,
'pending',
45.75,
2,
TIMESTAMP '2024-03-08 17:20:00',
NULL,
'Leave at the door;'
|| CHR(10)
|| 'ring twice',
NULL
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
6,
6,
'shipped',
310.4,
5,
TIMESTAMP '2024-03-10 13:00:00',
TIMESTAMP '2024-03-11 09:00:00',
'Fragile: "glass"',
NULL
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
7,
8,
'paid',
76.2,
2,
TIMESTAMP '2024-03-11 18:45:00',
NULL,
NULL,
NULL
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
8,
2,
'paid',
19.99,
1,
TIMESTAMP '2024-03-12 08:00:00',
NULL,
'Paid at the counter',
NULL
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
9,
3,
'shipped',
64,
2,
TIMESTAMP '2024-03-14 15:30:00',
NULL,
'Shipping date never recorded',
NULL
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
10,
7,
'paid',
1499,
1,
TIMESTAMP '2024-03-15 21:05:00',
NULL,
'C:\Users\ravi\invoice.pdf',
NULL
);
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_EMAIL" UNIQUE ("EMAIL");
ALTER TABLE "ORDERS" ADD CONSTRAINT "PK_ORDERS" PRIMARY KEY ("ID");
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") ON DELETE CASCADE 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 "CUSTOMERS";
    IF next_id < 9 THEN
        next_id := 9;
    END IF;
    EXECUTE IMMEDIATE 'ALTER TABLE "CUSTOMERS" 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 "ORDERS";
    IF next_id < 11 THEN
        next_id := 11;
    END IF;
    EXECUTE IMMEDIATE 'ALTER TABLE "ORDERS" MODIFY ("ID" GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH ' || next_id || '))';
END;
/
DROP FUNCTION "INTOSQL_CLOB";
DROP FUNCTION "INTOSQL_BLOB";
COMMIT;
EXIT;

修正

修正が必要な箇所はありませんでした。

確認が必要

  • ソースでは 1 個のテキスト列が大文字と小文字を区別せずに比較します。Oracle は厳密に比較するため、一意キーや検索の動作が変わる場合があります。 必要な列には、大文字と小文字を区別しない照合順序か列の型を使ってください。
  • 2 件のビュー、トリガー、ルーチン、イベントは変換されません。レポートにそれぞれ記載しています。 Oracle で手動で作り直してください。

ファイルはこのコンピューター上で変換され、アップロードされることはありません。

その他のサンプル:

SQLite から Oracle で変わること

各行はコンバーターが適用するルールです。ルールによってデータが変わったときにレポートに書かれる行も示します。

  • declared types (any text: VARCHAR(255), DATETIME, BOOLEAN, JSON or none)

    列のすべての値が収まる型

    SQLite はどの列にもどんな値でも保存できるため、宣言された型は目安です。各列にはすべての値が収まる型を付け、混在した値を持つ列はそのテキストを保ちます。

  • BOOLEAN, BOOL

    0 と 1 の CHECK 付きの NUMBER(1)

    すべての値が 0 か 1 の場合です。ほかの値も含む列は、それらを数値またはテキストとして保ちます。

  • TEXT, VARCHAR(n), CHAR(n), CLOB

    すべての値が収まれば VARCHAR2(n CHAR)、それ以外は CLOB

    SQLite は長さを強制しません。宣言された長さは、すべての値が収まる場合にだけ保ちます。

  • TEXT and VARCHAR(n) longer than 4000 bytes

    すべての値が 4000 バイト (キーでは 750 文字) に収まれば VARCHAR2(4000 CHAR)、それ以外は CLOB

    VARCHAR2 はデフォルトで 4000 バイトまでで、Oracle は CLOB にインデックスを作れません。そのため、テキストは値が収まれば VARCHAR2 のまま、収まらなければ CLOB になります。

    レポートの行: text_as_lob

  • DECIMAL(p,s), NUMERIC

    すべての値が収まれば正確な型、それ以外は double

    SQLite はこれらを整数または double として保存します。宣言された精度は、値が収まる場合にだけ保ちます。

  • BLOB, and columns holding bytes

    BLOB

    バイト列はバイト列のままです。同じ列にあるテキストや数値は、そのバイト列として保ちます。

  • DATE, DATETIME, TIMESTAMP holding ISO 8601 text

    値の内容に応じて DATE または TIMESTAMP(p)

    すべての値が日付、または日付と時刻の場合です。エポック形式の数値やほかのテキストは、値をそのまま保ちます。

  • JSON holding JSON text

    CLOB

    すべての値が JSON のオブジェクトまたは配列の場合です。

  • Infinity in REAL columns

    BINARY_DOUBLE_INFINITY として保持

    Oracle の double は無限大を保持できます。

  • INTEGER PRIMARY KEY, AUTOINCREMENT

    GENERATED BY DEFAULT ON NULL AS IDENTITY、最大の ID または sqlite_sequence の値の後から継続

    rowid になるのは、正確に INTEGER PRIMARY KEY と宣言された列だけです。各行は ID を保ち、カウンターはこれまでに割り当てられた最大の ID の後から始まります。

  • COLLATE NOCASE

    厳密な比較

    Oracle は指定がない限りテキストを厳密に比較します。NOCASE 列は大文字と小文字を区別しない動作を失います。

    レポートの行: case_insensitive_collation

  • generated columns

    仮想列

    Oracle は生成列を読み取り時にしか計算しません。STORED の列は同じ値を持つ仮想列になります。

    レポートの行: stored_as_virtual

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

    普通の列

    書き換えられない式は、普通の列とレポートの 1 行になります。ダンプには生成列の値が含まれません。

    レポートの行: generated_not_translated

  • defaults with functions IntoSQL doesn't write (strftime, randomblob)

    デフォルト値なし

    書き換えられないデフォルト値は含めず、レポートに記載します。CURRENT_TIMESTAMP と datetime('now') は書き出します。

    レポートの行: default_not_translated

  • CHECK constraints

    変換済み

    チェック制約は同じで、各行の読み込み時に検証します。

  • CHECK constraints with functions IntoSQL doesn't write

    作成しない

    書き換えられないチェック制約は含めず、レポートに記載します。

    レポートの行: check_skipped

  • partial and expression indexes

    作成しない

    IntoSQL が書き出すのは列全体に対するインデックスです。その他は読み込み後に作り直してください。

    レポートの行: index_skipped

  • foreign keys (unenforced unless PRAGMA foreign_keys=ON)

    データの後に ENABLE NOVALIDATE で作成してから検証

    SQLite は指示されたときにしか外部キーをチェックしないため、親のない行はよくあります。それらの行も読み込み、読み込みを止めずにキーを未チェックのまま残して警告します。

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

    削除

    Oracle の外部キーが動作するのは削除時だけで、CASCADE か SET NULL です。

    レポートの行: foreign_key_action_unsupported

  • empty strings and empty blobs

    NULL

    Oracle は空文字列を NULL として保存するため、' だった値は NULL として読み出されます。レポートで列ごとの件数を示します。

    レポートの行: empty_string_null

  • foreign keys to tables the dump doesn't create

    作成しない

    キーは存在しないテーブルを参照できません。

    レポートの行: foreign_key_skipped

  • primary keys holding NULL, and NOT NULL columns with values that become NULL

    NOT NULL を削除

    SQLite では rowid 以外の主キーが NULL を持てます。変換先ではその列を NOT NULL にできません。そうすると読み込みが止まります。

    レポートの行: not_null_relaxed

  • views, triggers and virtual tables (FTS, R*Tree)

    レポートに記載

    コードは SQLite 独自の言語で書かれており、仮想テーブルには SQLite のモジュールが必要です。作り直せるよう一覧にします。内部テーブルはコピーしません。

    レポートの行: not_converted_objects

  • dumps without CREATE TABLE (--data-only)

    値から読み取った型

    データのみのダンプには行しかないため、型は値から決まり、列には番号が付きます。

    レポートの行: no_schema

  • expressions in INSERT values other than the text functions dumps write

    NULL

    unistr()、replace()、char()、|| はシェルが書き出すとおりに評価します。その他の式はデータベースなしでは評価できません。

    レポートの行: expression_value

  • NUL characters in text

    保持

    sqlite3 シェルと Python はダンプ時に NUL 文字でテキストを切り詰めるため、ダンプにはその前の部分しか含まれません。

  • text that isn't valid UTF-8

    不正なバイトを置換文字に

    ダンプはこうしたテキストを生のバイトとして書き出します。スクリプトは UTF-8 です。

    レポートの行: invalid_utf8_replaced

  • text decoded twice (ñ)

    そのままコピー

    ダンプにはまさにこの文字が含まれているため、そのままコピーし、レポートで指摘します。

    レポートの行: mojibake_suspected

SQLite ではOracle ではレポートの行
declared types (any text: VARCHAR(255), DATETIME, BOOLEAN, JSON or none)列のすべての値が収まる型SQLite はどの列にもどんな値でも保存できるため、宣言された型は目安です。各列にはすべての値が収まる型を付け、混在した値を持つ列はそのテキストを保ちます。
BOOLEAN, BOOL0 と 1 の CHECK 付きの NUMBER(1)すべての値が 0 か 1 の場合です。ほかの値も含む列は、それらを数値またはテキストとして保ちます。
TEXT, VARCHAR(n), CHAR(n), CLOBすべての値が収まれば VARCHAR2(n CHAR)、それ以外は CLOBSQLite は長さを強制しません。宣言された長さは、すべての値が収まる場合にだけ保ちます。
TEXT and VARCHAR(n) longer than 4000 bytesすべての値が 4000 バイト (キーでは 750 文字) に収まれば VARCHAR2(4000 CHAR)、それ以外は CLOBVARCHAR2 はデフォルトで 4000 バイトまでで、Oracle は CLOB にインデックスを作れません。そのため、テキストは値が収まれば VARCHAR2 のまま、収まらなければ CLOB になります。text_as_lob
DECIMAL(p,s), NUMERICすべての値が収まれば正確な型、それ以外は doubleSQLite はこれらを整数または double として保存します。宣言された精度は、値が収まる場合にだけ保ちます。
BLOB, and columns holding bytesBLOBバイト列はバイト列のままです。同じ列にあるテキストや数値は、そのバイト列として保ちます。
DATE, DATETIME, TIMESTAMP holding ISO 8601 text値の内容に応じて DATE または TIMESTAMP(p)すべての値が日付、または日付と時刻の場合です。エポック形式の数値やほかのテキストは、値をそのまま保ちます。
JSON holding JSON textCLOBすべての値が JSON のオブジェクトまたは配列の場合です。
Infinity in REAL columnsBINARY_DOUBLE_INFINITY として保持Oracle の double は無限大を保持できます。
INTEGER PRIMARY KEY, AUTOINCREMENTGENERATED BY DEFAULT ON NULL AS IDENTITY、最大の ID または sqlite_sequence の値の後から継続rowid になるのは、正確に INTEGER PRIMARY KEY と宣言された列だけです。各行は ID を保ち、カウンターはこれまでに割り当てられた最大の ID の後から始まります。
COLLATE NOCASE厳密な比較Oracle は指定がない限りテキストを厳密に比較します。NOCASE 列は大文字と小文字を区別しない動作を失います。case_insensitive_collation
generated columns仮想列Oracle は生成列を読み取り時にしか計算しません。STORED の列は同じ値を持つ仮想列になります。stored_as_virtual
generated columns with functions IntoSQL doesn't write, and the || operator普通の列書き換えられない式は、普通の列とレポートの 1 行になります。ダンプには生成列の値が含まれません。generated_not_translated
defaults with functions IntoSQL doesn't write (strftime, randomblob)デフォルト値なし書き換えられないデフォルト値は含めず、レポートに記載します。CURRENT_TIMESTAMP と datetime('now') は書き出します。default_not_translated
CHECK constraints変換済みチェック制約は同じで、各行の読み込み時に検証します。
CHECK constraints with functions IntoSQL doesn't write作成しない書き換えられないチェック制約は含めず、レポートに記載します。check_skipped
partial and expression indexes作成しないIntoSQL が書き出すのは列全体に対するインデックスです。その他は読み込み後に作り直してください。index_skipped
foreign keys (unenforced unless PRAGMA foreign_keys=ON)データの後に ENABLE NOVALIDATE で作成してから検証SQLite は指示されたときにしか外部キーをチェックしないため、親のない行はよくあります。それらの行も読み込み、読み込みを止めずにキーを未チェックのまま残して警告します。
ON UPDATE CASCADE, SET NULL or SET DEFAULT; ON DELETE SET DEFAULT削除Oracle の外部キーが動作するのは削除時だけで、CASCADE か SET NULL です。foreign_key_action_unsupported
empty strings and empty blobsNULLOracle は空文字列を NULL として保存するため、' だった値は NULL として読み出されます。レポートで列ごとの件数を示します。empty_string_null
foreign keys to tables the dump doesn't create作成しないキーは存在しないテーブルを参照できません。foreign_key_skipped
primary keys holding NULL, and NOT NULL columns with values that become NULLNOT NULL を削除SQLite では rowid 以外の主キーが NULL を持てます。変換先ではその列を NOT NULL にできません。そうすると読み込みが止まります。not_null_relaxed
views, triggers and virtual tables (FTS, R*Tree)レポートに記載コードは SQLite 独自の言語で書かれており、仮想テーブルには SQLite のモジュールが必要です。作り直せるよう一覧にします。内部テーブルはコピーしません。not_converted_objects
dumps without CREATE TABLE (--data-only)値から読み取った型データのみのダンプには行しかないため、型は値から決まり、列には番号が付きます。no_schema
expressions in INSERT values other than the text functions dumps writeNULLunistr()、replace()、char()、|| はシェルが書き出すとおりに評価します。その他の式はデータベースなしでは評価できません。expression_value
NUL characters in text保持sqlite3 シェルと Python はダンプ時に NUL 文字でテキストを切り詰めるため、ダンプにはその前の部分しか含まれません。
text that isn't valid UTF-8不正なバイトを置換文字にダンプはこうしたテキストを生のバイトとして書き出します。スクリプトは UTF-8 です。invalid_utf8_replaced
text decoded twice (ñ)そのままコピーダンプにはまさにこの文字が含まれているため、そのままコピーし、レポートで指摘します。mojibake_suspected

スクリプトを Oracle に読み込む

スクリプトはテーブルを作成して行をコピーしてから、キー、インデックス、外部キーを追加します。そのため読み込みが速く、最初のエラーで止まります。

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

外部キーは ENABLE NOVALIDATE で追加するため新しい行はすぐにチェックされ、その後に検証します。古い行が存在しない行を参照していれば、途中で失敗する代わりに、どの制約かをスクリプトが示し、その制約は未検証のまま残します。

大きなダンプでは、データベースと同じマシンで SQL*Plus を実行してください。スクリプトは 100 行ごとにコミットします。実行するユーザーには CREATE TABLE、CREATE SEQUENCE、CREATE TRIGGER、CREATE PROCEDURE の権限と、表領域の割り当てが必要です。

SQLite を最適な方法でダンプする

コンバーターはダンプの内容を読み取ります。次のオプションを使うと、より多くのデータがダンプに残ります。

  • データベースファイル自体をそのまま変換し、ブラウザでページ単位で読み込みます。変更が -wal ファイルに残らないよう、先に書き込み中のアプリを閉じてください。
  • sqlite3 app.db .dump > app.sql で同じデータベースを SQL として書き出せます。これも .sql または .sql.gz として変換できます。
  • DB Browser for SQLite では File、Export、Database to SQL file の順に選ぶとその SQL を書き出せます。Python の iterdump() も同様です。

変換されないもの

ビューとトリガーは SQLite 独自の言語で書かれています。黙って削除することはなく、レポートに名前で一覧するので、Oracle 向けに書き直せます。FTS5 や R*Tree などの仮想テーブルも一覧し、そのシャドウテーブルは含めません。

SQLite から Oracle への変換に関する質問

ここに答えがない場合は、お問い合わせページからご連絡ください。担当者が返信します。 お問い合わせページ

ダンプはアップロードされますか?

いいえ。コンバーターはブラウザ上で動作し、ダンプをディスクから少しずつ読み込むため、ダンプがコンピューターの外に出ることはありません。デスクトップアプリとコマンドラインも、お使いのコンピューター上で変換します。

ダンプはどのくらいの大きさまで扱えますか?

コンバーターはダンプ全体をメモリに保持しません。ファイルを範囲ごとに 2 回読み、読みながらスクリプトを書き出します。数 GB のダンプも、ブラウザ、デスクトップアプリ、コマンドラインで変換できます。

.db ファイル自体を変換できますか?

はい。.db、.sqlite、.sqlite3 ファイルをドロップしてください。ブラウザで読み込まれ、アップロードされることはありません。NUL 文字を含むテキストや double のすべての桁も保存されたとおりに届きます。.dump ではこれらが欠けることがあります。

どの SQLite バージョンのダンプに対応していますか?

SQLite 3.0 以降の UTF-8 または UTF-16 のデータベースファイルと、sqlite3 シェルの .dump または Python の iterdump() で作成したダンプです。すべてのテスト用ファイルとダンプは sqlite3 3.31 から 3.54 で作成し、STRICT と WITHOUT ROWID のテーブルも含め、ソースとセル単位で比較しています。

SQLite が型を強制しない場合、列の型はどう決まりますか?

宣言された型は目安で、値によって決まります。すべての値が収まれば、列は NUMBER、BINARY_DOUBLE、DATE、TIMESTAMP、BLOB、VARCHAR2、CLOB のいずれかになります。空文字列は Oracle の保存方法どおり NULL になり、レポートで件数を示します。

INTEGER PRIMARY KEY と AUTOINCREMENT は保持されますか?

はい。INTEGER PRIMARY KEY は identity 列になり、各行は ID を保ちます。次の ID は最大の ID の後から、AUTOINCREMENT がある場合は sqlite_sequence の値の後から続きます。

ビューとトリガーはどうなりますか?

データベースごとに独自の言語で書かれるため、変換はせず、レポートに名前で一覧します。

スクリプトはどの Oracle バージョンで読み込めますか?

Oracle 19c 以降です。すべてのテスト用ダンプを 21c と 23ai で読み込み、問題があれば最初のエラーで止まります。