原文鏈接:https://dev.to/yugabyte/sqlcl-to-transfer-data-from-oracle-to-postgresql-or-yugabytedb-lha
原文作者:Franck Pachot
以前的dba有過這樣的故事:oracle提供了一個“SQLLoader”而沒有任何“SQLUnloader”,因為Larry Ellison 不希望他的客戶搬走。 現在已經改變了:有一種簡單的方法可以使用簡單set sqlformat csv的 SQLcl 導出到 CSV。 關注Jeff Smith 博客以了解更多信息。
舉個例子。 我想將一些示例數據從Oracle移動到YugabyteDB以比較大小。 我有一個始終免費的自治數據庫,其中包括 SSB 示例模式。有一個LINEORDER表,大小為幾百GB。 我將使用dbms_metadata獲取DDL。 我必須做的唯一更改是sub(" NUMBER,"," NUMERIC,")禁用約束和排序規則。
當然,有一些專業工具可以將Oracle模式轉換為PostgreSQL。好的舊的ora2pg或 AWS?SCT也非常適合評估遷移所需的更改級別。但是對于一些快速的操作,我很擅長使用awk??
然后,通過設置set sqlformat csv和一些只輸出數據的設置,如feedback off pagesize 0 long 999999999 verify off,導出就很容易了。我將所有awk構建\copy命令的所有內容都通過管道傳遞給這些 CSV 行。 我喜歡先執行一些小步驟,然后在 COPY 命令的開頭設置 10000 行 COPY(NR-data)%10000命令data。并行發送它們很容易,但我可能不需要它,因為YugabyteDB是多線程的。
這是我使用的腳本 - 我在 TNS_ADMIN 中有我的自治數據庫錢包,我家中安裝了 SQLcl(一個 Oracle 免費層 ARM,我也在其上運行我的 YugabyteDB 實驗)。
{
TNS_ADMIN=/home/opc/wallet_oci_fra ~/sqlcl/bin/sql -s demo/",,P455w0rd,,"@o21c_tp @ /dev/stdin SSB LINEORDER <<SQL
set feedback off pagesize 0 long 999999999 verify off
whenever sqlerror exit failure
begin
dbms_metadata.set_transform_param(dbms_metadata.session_transform, 'SEGMENT_ATTRIBUTES', false);
dbms_metadata.set_transform_param(dbms_metadata.session_transform, 'STORAGE', false);
dbms_metadata.set_transform_param(dbms_metadata.session_transform, 'CONSTRAINTS', false);
dbms_metadata.set_transform_param(dbms_metadata.session_transform, 'REF_CONSTRAINTS', false);
dbms_metadata.set_transform_param(dbms_metadata.session_transform, 'SQLTERMINATOR', true);
dbms_metadata.set_transform_param(dbms_metadata.session_transform, 'COLLATION_CLAUSE', 'NEVER');
end;
/
set sqlformat default
select dbms_metadata.get_ddl('TABLE','&2','&1') from dual ;
set sqlformat csv
select * from "&1"."&2" ;
SQL
} | awk '
/^ *CREATE TABLE /{
table=$0 ; sub(/^ *CREATE TABLE/,"",table)
print "drop table if exists "table";"
schema=table ; sub(/\"[.]\".*/,"\"",schema)
print "create schema if not exists "schema";"
}
/^"/{
data=NR-1
print "\\copy "table" from stdin with csv header"
}
data<1{
sub(" NUMBER,"," numeric,")
}
{print}
data>0 && (NR-data)%1000000==0{
print "\\."
print "\\copy "table" from stdin with csv"
}
END{
print "\\."
}
'
輸出可以直接通過管道傳輸到psql??
這是一個實驗,測量運行時間沒有意義,但我查看了rows_inserted統計信息,以驗證所有數據都分布在分布式SQL數據庫的3個節點上。 即使使用單個客戶端會話,負載也會分布在所有集群上。
這對于PostgreSQL也是一樣的,因為它們是相同的API: YugabyteDB在分布式存儲上使用了PostgreSQL。
此測試中的所有組件都是免費且易于使用的:
- 虛擬機位于 Oracle 云免費層 (ARM) 上,Oracle 數據庫是免費的自治數據庫 ???https://www.oracle.com/cloud/free/
- PostgreSQL 是開源免費的???https://www.postgresql.org
- YugabyteDB 是開源免費的???https://www.yugabyte.com





