oci8 擴展(Oracle 連線)。mysqli/PDO)。SELECT table_name FROM user_tables;
SELECT column_name, data_type, data_length, nullable, data_default
FROM user_tab_columns
WHERE table_name = UPPER(:tname)
ORDER BY column_id;
| Oracle | MySQL |
|---|---|
| NUMBER(p) p<11 | INT |
| NUMBER(p) p>=11 | BIGINT |
| VARCHAR2(n) n<=255 | VARCHAR(n) |
| VARCHAR2(n) n>255 | TEXT |
| CLOB | TEXT / LONGTEXT |
| DATE | DATETIME |
| TIMESTAMP | DATETIME(6) |
| BLOB | BLOB / LONGBLOB |
⚠️ Oracle 無自增欄位,**PK 改為 MySQL AUTO_INCREMENT**(需識別 Sequence 關聯欄位,或統一 PK 設自增)。
-- PK/UK/FK
SELECT c.constraint_name, c.constraint_type, c.r_constraint_name, c.delete_rule,
cc.column_name
FROM user_constraints c, user_cons_columns cc
WHERE c.table_name = UPPER(:tname)
AND c.constraint_type != 'C'
AND c.constraint_name = cc.constraint_name
AND c.owner = cc.owner
AND c.table_name = cc.table_name
ORDER BY c.constraint_type, c.constraint_name, cc.position;
-- Index
SELECT t.index_name, t.column_name, i.index_type
FROM user_ind_columns t, user_indexes i
WHERE t.index_name = i.index_name
AND t.table_name = i.table_name
AND t.table_name = UPPER(:tname);
CREATE TABLE DDL依序:欄位定義 → PK → UK → FK → Index。注意 MySQL FK 需 InnoDB、參考表先建立。
SELECT view_name, text FROM user_views;
**不兼容處理**:MySQL View 不允許 FROM (subquery) 直接建立。
解法:將子查詢另建為 Base View,主 View 引用 Base View。
SELECT Oracle 資料(游標分批,避免記憶體爆炸)。TO_CHAR(dt, 'YYYY-MM-DD HH24:MI:SS') 符合 MySQL DATETIME 格式。oci_fetch_array($stid, OCI_ASSOC|OCI_RETURN_NULLS|OCI_RETURN_LOBS) 取出完整內容寫入 MySQL TEXT。INSERT 或 LOAD DATA 批次寫入。[mysqld]
max_allowed_packet = 16M -- Windows 預設 1M 導致大 CLOB/TEXT 匯入失敗
innodb_buffer_pool_size = 1G -- 視記憶體調大
bulk_insert_buffer_size = 64M
Linux 預設 16M 通常無問題。
DESC 對比、行數 COUNT(*) 對比。Oracle → MySQL 遷移:**結構與資料可高度自動化**,View 需中介轉換,**程式碼物件必須人工重寫**。關鍵在於**精準型別映射、CLOB/日期處理、MySQL 參數預調、分批提交與雙向驗證**。