Oracle
使用 Excel/CSV 文件中的數據重新填充 Oracle 表
我正在開發一個利用 Hibernate/JPA 的 Java EE 應用程序。我想使用的一些數據來自另一個業務部門的電子表格,我需要定期(重新)載入到 5 個 Oracle 表中,覆蓋任何現有數據。我正在使用一個啟動 5 個 sql*loader 控製文件的 shell 腳本,其中每個控製文件都指定要跳過的填充欄位,因為 excel 文件未規範化。
OPTIONS(skip=2) load data REPLACE --######################################### into table TABLE_NAME fields terminated by "," optionally enclosed by '"' TRAILING NULLCOLS ( ACCOUNT_ID , REST_STOP_ID , DESCRIPTION FILLER , GROUP FILLER , FUNCTION , JOB_ID "substr(:JOB_ID, 0, INSTR(:JOB_ID,' - ',1))", <35 other fields> etc...
首次使用 SQLLoader 將這些數據導入空表和來自該電子表格的 csv 文件可以正常工作。但是隨後任何後續執行 sqlloader 都會失敗,因為任一控製文件選項:
使用替換時:
SQL*Loader-926: OCI error while executing delete/truncate (due to REPLACE/TRUNCATE keyword) **ORA-02292:** integrity constraint (SCHEMA.FK5BA979794B0A176A) violated - child record found
使用截斷時:
SQL*Loader-926: OCI error while executing delete/truncate (due to REPLACE/TRUNCATE keyword) **ORA-02266:** unique/primary keys in table referenced by enabled foreign keys
我還嘗試重新排序填充了哪些表格,但沒有運氣。
我也嘗試過禁用約束
ALTER TABLE TABLE_NAME DISABLE CONSTRAINT SYS_C0090398 ORA-02297: cannot disable constraint (SCHEMA.SYS_C0090398) - dependencies exist (0 rows affected)
到目前為止,我的工作是刪除所有表重新啟動我的應用程序並讓 Hibernate 重新創建我的 5 個表,然後執行我的 sql*loader 腳本。現在我正在開發中,所以沒什麼大不了的。但是當我們投入生產時,我無法繼續重新啟動和創建表。實際上,當我投入生產時,我會在 hibernate 之外創建表,但現在我將持久性選項
hibernate.hbm2ddl.auto
設置為update
.我正在尋找一種優雅的(半)自動解決方案,以使用 csv/Excel 文件中提供給我的數據定期重新填充這 5 個表。
對於可重用的數據載入,我更喜歡定義從 CSV 文件讀取的靜態外部表。您需要一個 Oracle
DIRECTORY
對象來讀取該文件。此範例創建一個名為的五列外部表,該表從目錄
FOO_TAB
中讀取FOO_TAB.CSV
文件。FOO_DIR
CREATE TABLE foo_tab ( a1 VARCHAR2(4000), a2 VARCHAR2(4000), a3 VARCHAR2(4000), a4 VARCHAR2(4000), a5 VARCHAR2(4000), ) ORGANIZATION EXTERNAL ( TYPE ORACLE_LOADER DEFAULT DIRECTORY foo_dir ACCESS PARAMETERS ( RECORDS DELIMITED BY newline BADFILE 'foo_tab.bad' DISCARDFILE 'foo_tab.dis' LOGFILE 'foo_tab.log' SKIP 1 /* first row just has column headers */ FIELDS TERMINATED BY "," OPTIONALLY ENCLOSED BY '"' LTRIM MISSING FIELD VALUES ARE NULL ( a1 CHAR(4000), a2 CHAR(4000), a3 CHAR(4000), a4 CHAR(4000), a5 CHAR(4000), ) ) LOCATION (foo_dir:'foo_tab.csv') ) REJECT LIMIT UNLIMITED;
唯一的方法是在執行載入程序之前禁用引用約束。然後在之後啟用它們 - 希望新數據是一致的。