在 Oracle 數據庫中,我們通常在不同數據庫的表間記錄進行復制或遷移時會用以下幾種方法:
1. 逐條insert -- 只適用少量數據更新
ALTER TABLE order_items DISABLE CONSTRAINT fk_order_items_products; alter table OT.ORDER_ITEMS nologging; --關閉日志可提高性能 REM INSERTING into OT.ORDER_ITEMS SET DEFINE OFF; Insert /* +APPEND */ into OT.ORDER_ITEMS (ORDER_ID,ITEM_ID,PRODUCT_ID,QUANTITY,UNIT_PRICE) values (70,7,32,132,469.99); Insert /* +APPEND */ into OT.ORDER_ITEMS (ORDER_ID,ITEM_ID,PRODUCT_ID,QUANTITY,UNIT_PRICE) values (73,5,192,124,519.99); ALTER TABLE order_items ENABLE CONSTRAINT fk_order_items_products;
2. 建立數據庫間的 dblink
create table B as select * from A@dblink where ... insert into B select * from A@dblink where ...
3. exp A表(可加查詢條件),再imp到B表
imp操作導入dmp文件時表空間問題 1.創建表空間, 2.indexfile並運行,再執行導入, 3.修改默認表空間
create user myhuang identified by myhuang default tablespace myhuang; grant resource,connect to myhuang; grant dba to myhuang; //賦DBA權限 revoke unlimited tablespace from myhuang; //撤銷此權限 alter user myhuang quota 0 on system; //將用戶在System表空間的配額置為0 alter user myhuang quota unlimited on myhuang; //設置在用戶在myhuang表空間配額不受限。
exp test/test@ip:1521/ORCL file=D:\360Downloads\test.dmp tables=(BMB,HCK_1018,ZC_CGDD_1018)
imp test/test@ip:1521/ORCL file=D:\360Downloads\test.dmp tables=(HCK_1018,ZC_CGDD_1018) ignore=y
數據導出: 1 將數據庫TEST完全導出,用戶名system 密碼manager 導出到D:\daochu.dmp中 exp system/manager@TEST file=d:\daochu.dmp full=y 2 將數據庫中system用戶與sys用戶的表導出 exp system/manager@TEST file=d:\daochu.dmp owner=(system,sys) 3 將數據庫中的表table1 、table2導出 exp system/manager@TEST file=d:\daochu.dmp tables=(table1,table2) 4 將數據庫中的表table1中的字段filed1以"00"打頭的數據導出 exp system/manager@TEST file=d:\daochu.dmp tables=(table1) query=\" where filed1 like '00%'\" 上面是常用的導出,對於壓縮我不太在意,用winzip把dmp文件可以很好的壓縮。不過在上面命令后面 加上 compress=y 就可以了 數據導入: 1 將D:\daochu.dmp 中的數據導入 TEST數據庫中。 imp system/manager@TEST file=d:\daochu.dmp 上面可能有點問題,因為有的表已經存在,然后它就報錯,對該表就不進行導入。 在后面加上 ignore=y 就可以了。 2 將d:\daochu.dmp中的表table1 導入 imp system/manager@TEST file=d:\daochu.dmp tables=(table1)
4. 程序分批執行
select from A ..
insert into B ...
5. Sql Loader(sqlldr / sqluldr2)
實例:
1) 數據文件+建表
2) ctl文件-
--不包含數據文件 OPTIONS (skip=1,rows=128) unrecoverable -- 關閉數據庫的日志,此選項必須要與DIRECT共同應用 LOAD DATA INFILE "users_data.csv" -- 可以 INFILE "another_data_file.csv" 指定多個數據文件,還可以使用 BADFILE、DISCARDFILE 來指定壞數據和丟棄數據的文件, "fix n" "var n" truncate -- 操作類型,truncate=清除表中原有記錄,還可insert INTO TABLE users -- 要插入記錄的表 Fields terminated by "," -- 數據中每行記錄用 "," 分隔 Optionally enclosed by '"' -- 數據中每個字段用 '"' 框起,比如字段中有 "," 分隔符時 trailing nullcols -- 表的字段沒有對應的值時允許為空 ( virtual_column FILLER, -- FILLER 指定虛擬字段,用來跳過序號等 user_id number, -- 指定字段類型,默認 CHARACTER 類型, log 中有顯示 user_name, login_times, last_login DATE "YYYY-MM-DD HH24:MI:SS" -- 指定接受日期的格式,相當用 to_date() 函數轉換 ) --包含數據文件 OPTIONS (skip=1,rows=128) LOAD DATA INFILE * -- 因為數據同控制文件在一起,所以用 * 表示 append -- append 操作表示在表 users 中附加記錄 INTO TABLE users when LOGIN_TIMES<>'8' -- 還可以用 when 子句篩選符合條件的記錄 Fields terminated by "," trailing nullcols ( virtual_column FILLER, --prod_id char(32) "trim(:prod_id)", --acc_num char(20) "replace(:acc_num,chr(13),'')" user_id "user_seq.nextval", --這一列直接取序列的下一值,而不用數據中提供的值 user_name "'Hi '||upper(:user_name)", -- 還能用SQL函數或運算對數據進行加工處理 login_times terminated by ",", NULLIF(login_times='NULL'), --可為列單獨指定分隔符 last_login DATE "YYYY-MM-DD HH24:MI:SS" NULLIF (last_login="NULL") -- 當字段為"NULL"時就是 NULL ) BEGINDATA --數據從這里開始 ,USER_ID,USER_NAME,LOGIN_TIMES,LAST_LOGIN 1,1,Unmi,3,2009-1-5 20:34 2,2,Fantasia,5,2008-10-15 3,3,隔葉黃鶯,8,2009-1-2 4,4,Kypfos,NULL,NULL 5,5,不知秋,1,2008-12-23
sqluldr2自動生成的ctl文件
-- -- SQL*UnLoader: Fast Oracle Text Unloader (GZIP), Release 3.0.1 -- (@) Copyright Lou Fangxin (AnySQL.net) 2004 - 2010, all rights reserved. -- -- CREATE TABLE qmcb_ls_100 ( -- AAC002 VARCHAR2(18), -- AAB301_AC02 VARCHAR2(6), -- AAB301_ZCA1 VARCHAR2(12), -- BAB004 VARCHAR2(20), -- AAC300 VARCHAR2(20), -- AAC301 VARCHAR2(6), -- AAC012 VARCHAR2(12), -- AAC049 NUMBER(6), -- AAE030 NUMBER(8), -- AAE031 NUMBER(8), -- AAC004 VARCHAR2(40), -- AAC005 VARCHAR2(5), -- AAC006 NUMBER, -- AAC011 VARCHAR2(2), -- AAC017 VARCHAR2(1), -- AAC058 VARCHAR2(2), -- AAC161 VARCHAR2(3), -- AAC009 VARCHAR2(2), -- AAC154 VARCHAR2(1), -- AAC204 VARCHAR2(1), -- BAC020 VARCHAR2(1), -- BAC015 VARCHAR2(1), -- BAE185 VARCHAR2(1), -- NUM_OF_EMPS NUMBER, -- IS_ZD VARCHAR2(1), -- IS_REG_POPU VARCHAR2(1), -- LABEL VARCHAR2(1) -- ); -- OPTIONS(BINDSIZE=2097152,READSIZE=2097152,SKIP=1,ERRORS=-1,ROWS=50000) LOAD DATA INFILE 'c:\oracle\sqluldr2\qmcb_ls_100.csv' "STR X'0a'" INSERT INTO TABLE qmcb_ls_100 FIELDS TERMINATED BY X'2c' TRAILING NULLCOLS ( "AAC002" CHAR(18) NULLIF "AAC002"=BLANKS, "AAB301_AC02" CHAR(6) NULLIF "AAB301_AC02"=BLANKS, "AAB301_ZCA1" CHAR(12) NULLIF "AAB301_ZCA1"=BLANKS, "BAB004" CHAR(20) NULLIF "BAB004"=BLANKS, "AAC300" CHAR(20) NULLIF "AAC300"=BLANKS, "AAC301" CHAR(6) NULLIF "AAC301"=BLANKS, "AAC012" CHAR(12) NULLIF "AAC012"=BLANKS, "AAC049" CHAR(8) NULLIF "AAC049"=BLANKS, "AAE030" CHAR(10) NULLIF "AAE030"=BLANKS, "AAE031" CHAR(10) NULLIF "AAE031"=BLANKS, "AAC004" CHAR(40) NULLIF "AAC004"=BLANKS, "AAC005" CHAR(5) NULLIF "AAC005"=BLANKS, "AAC006" CHAR(46) NULLIF "AAC006"=BLANKS, "AAC011" CHAR(2) NULLIF "AAC011"=BLANKS, "AAC017" CHAR(1) NULLIF "AAC017"=BLANKS, "AAC058" CHAR(2) NULLIF "AAC058"=BLANKS, "AAC161" CHAR(3) NULLIF "AAC161"=BLANKS, "AAC009" CHAR(2) NULLIF "AAC009"=BLANKS, "AAC154" CHAR(1) NULLIF "AAC154"=BLANKS, "AAC204" CHAR(1) NULLIF "AAC204"=BLANKS, "BAC020" CHAR(1) NULLIF "BAC020"=BLANKS, "BAC015" CHAR(1) NULLIF "BAC015"=BLANKS, "BAE185" CHAR(1) NULLIF "BAE185"=BLANKS, "NUM_OF_EMPS" CHAR(46) NULLIF "NUM_OF_EMPS"=BLANKS, "IS_ZD" CHAR(1) NULLIF "IS_ZD"=BLANKS, "IS_REG_POPU" CHAR(1) NULLIF "IS_REG_POPU"=BLANKS, "LABEL" CHAR(1) NULLIF "LABEL"=BLANKS )
3) 執行
導出:
D:\oracle\sqluldr2>sqluldr264 scott/s123 query="select * from qmcb_ls_100" table=qmcb_ls_100 head=yes file=d:\oracle\sqluldr2\qmcb_ls_100.csv
D:\oracle\sqluldr2>sqluldr264 scott/s123@xxx:1521/xxx sql=d:\oracle\sqluldr2\qmcb_ls.sql table=qmcb_ls head=yes file=d:\oracle\sqluldr2\qmcb_ls.csv
導入:
C:\Users\epsoft>sqlldr userid=scott/s123 control=d:\oracle\sqluldr2\qmcb_ls_100.ctl data=d:\oracle\sqluldr2\qmcb_ls_100.csv direct=true parallel=true
sqlldr dbuser/dbpass@dbservice control=users.ctl
當加載大量數據時(大約超過10GB),最好抑制日志的產生, 這樣不產生REDO LOG,可以提高效率。
SQL>ALTER TABLE RESULTXT nologging;
然后在 CONTROL 文件中 load data 上面加一行:unrecoverable,此選項必須要與DIRECT共同應用。
parallel並不是讓一個sqlldr語句起多個進程來加載數據,而是不鎖住加載表,允許別的直接路徑加載. 所以要使parallel起作用,應該先將要加載的數據文件分成多個,用多個sqlldr語句同時加載,如下例:
並行
sqlldr userid=/ control=result1.ctl direct=true parallel=true
sqlldr userid=/ control=result2.ctl direct=true parallel=true
參考資料:
Oracle SqlLoader使用
sqluldr2的使用及常見異常處理
sqluldr2 學習心得
sqlldr官方文檔
sqluldr2官方文檔
Oracle Sql Loader的學習使用
load data infile
python3腳本使用sql loader批量導入字節文件並二次處理
https://www.cnblogs.com/lideng/p/3739380.html
參數說明
userid -- ORACLE的 username/password[@servicename] control -- 控制文件名(可包含數據) log -- 日志文件名 bad -- 錯誤文件名 data -- 數據文件名 discard -- 廢棄文件名 discardmax -- 允許廢棄的文件的數目 (全部默認) skip -- 要跳過的邏輯記錄的數目 (默認 0) load -- 要加載的邏輯記錄的數目 (全部默認) errors -- 允許的錯誤的數目 (默認 50) rows -- 常規路徑綁定數組中或直接路徑保存數據間的行數 (默認: 常規路徑 64, 所有直接路徑) bindsize -- 常規路徑綁定數組的大小 (以字節計) (默認 256000) silent -- 運行過程中隱藏消息 all|(HEADER, FEEDBACK,ERROR,廢棄,DISCARD) direct -- 使用直接路徑(默認 FALSE),導入時跳過數據庫的相關邏輯,風險:如果主鍵重復的話會使索引的狀態變成UNUSABLE parfile -- 參數文件: 包含參數說明的文件的名稱 parallel -- 執行並行加載 (默認 FALSE) file -- 要從以下對象中分配區的文件 readsize -- 讀取緩沖區的大小 (默認 1048576) table -- 用於快速模式加載的表 optionally_enclosed_by -- (可選) 由用於快速模式加載的字符封閉 skip_unusable_indexes -- 不允許/允許使用無用的索引或索引分區 (默認 FALSE) skip_index_maintenance -- 沒有維護索引, 將受到影響的索引標記為無用 (默認 FALSE) commit_discontinued -- 提交加載中斷時已加載的行 (默認 FALSE) external_table -- 使用外部表進行加載; NOT_USED, GENERATE_ONLY, EXECUTE columnarrayrows -- 直接路徑列數組的行數 (默認 5000) streamsize -- 直接路徑流緩沖區的大小 (以字節計) (默認 256000) multithreading -- 在直接路徑中使用多線程 resumable -- 對當前會話啟用或禁用可恢復 (默認 FALSE) resumable_name -- 有助於標識可恢復語句的文本字符串 resumable_timeout -- RESUMABLE 的等待時間 (以秒計) (默認 7200) date_cache -- 日期轉換高速緩存的大小 (以條目計) (默認 1000) no_index_errors -- 出現任何索引錯誤時中止加載 (默認 FALSE) partition_memory -- 開始溢出的直接路徑分區內存限制 (kb) (默認 0) date_format -- 用於快速模式加載的日期格式 timestamp_format -- 用於快速模式加載的時間戳格式 terminated_by -- 由用於快速模式加載的字符終止 enclosed_by -- 由用於快速模式加載的字符封閉 characterset -- 用於快速模式加載的字符集 degree_of_parallelism -- 用於快速模式加載和外部表加載的並行度 trim -- 用於快速模式加載和外部表加載的截取類型 csv -- 用於快速模式加載的 csv 格式數據文件 nullif -- 用於快速模式加載的表級 nullif 子句 field_names -- 用於快速模式加載的數據文件第一條記錄字段名設置 dnfs_enable -- 啟用或禁用輸入數據文件 Direct NFS (dNFS) 的選項 (默認 FALSE) dnfs_readbuffers -- Direct NFS (dNFS) 讀緩沖區數 (默認 4) control選項: ------------------------------------------------------------------------------------------------------- log -- 記錄導入時的日志文件,默認為 控制文件(去除擴展名).log bad -- 壞數據文件,默認為 控制文件(去除擴展名).bad data -- 數據文件,一般在控制文件中指定。用參數控制文件中不指定數據文件更適於自動操作 errors -- 允許的錯誤記錄數,可以用他來控制一條記錄都不能錯 rows -- 多少條記錄提交一次,默認為 64 skip -- 跳過的行數,比如導出的數據文件前面幾行是表頭或其他描述 操作類型 1) insert --為缺省方式,在數據裝載開始時要求表為空 2) append --在表中追加新記錄 3) replace --刪除舊記錄(用 delete from table 語句),替換成新裝載的記錄 4) truncate --刪除舊記錄(用 truncate table 語句),替換成新裝載的記錄