[英]Continuing Inserts in Oracle when exception is raised
我正在努力將數據從遺留系統遷移到我們的新應用程序(在Oracle數據庫10gR2上運行)。 作為遷移的一部分,我正在編寫一個腳本,將數據插入到應用程序使用的表中。
導入的數據行數達到數千,而源數據不干凈(NOT NULL列中的意外空值等)。 因此,在通過腳本插入數據時,只要發生此類異常,腳本就會突然結束,並回滾整個事務。
有沒有辦法可以繼續插入行清理的數據? 使用NVL()
或COALESCE()
不是一個選項,因為我想記錄導致錯誤的行,以便可以為下一次傳遞更正數據。
編輯:我當前的程序有一個異常處理程序,我正在記錄導致錯誤的第一行。 插入是否可能在沒有終止的情況下繼續,因為現在在第一個處理的異常上,該過程終止執行。
如果數據量較高,PL / SQL中的逐行處理可能會太慢。 在這些情況下,您可以使用此處描述的DML錯誤日志記錄
CREATE TABLE raises (emp_id NUMBER, sal NUMBER
CONSTRAINT check_sal CHECK(sal > 8000));
EXECUTE DBMS_ERRLOG.CREATE_ERROR_LOG('raises', 'errlog');
INSERT INTO raises
SELECT employee_id, salary*1.1 FROM employees
WHERE commission_pct > .2
LOG ERRORS INTO errlog ('my_bad') REJECT LIMIT 10;
SELECT ORA_ERR_MESG$, ORA_ERR_TAG$, emp_id, sal FROM errlog;
ORA_ERR_MESG$ ORA_ERR_TAG$ EMP_ID SAL
--------------------------- -------------------- ------ -------
ORA-02290: check constraint my_bad 161 7700
(HR.SYS_C004266) violated
使用PLSQL,您可以在自己的事務中執行每個插入(在每個事務之后執行COMMIT),並使用異常處理程序記錄或忽略錯誤。
嘗試這個:
for r_row in c_legacy_data loop
begin
insert into some_table(a, b, c, ...)
values (r_row.a, r_row.b, r_row.c, ...);
exception
when others then
null; /* or some extra logging */
end;
end loop;
DECLARE
cursor;
BEGIN
loop for each row in cursor
BEGIN -- subBlock begins
SAVEPOINT startTransaction; -- mark a savepoint
-- do whatever you have do here
COMMIT;
EXCEPTION
ROLLBACK TO startTransaction; -- undo changes
END; -- subBlock ends
end loop;
END;
如果使用sqlldr,則可以指定繼續加載數據,並且將跳過所有“錯誤”數據並將其記錄在單獨的文件中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.