2012-07-23 37 views
0

我們有一個表EVAPP_INTERFACE,它沒有在多個數字列上指定比例或精度。我們需要修改列定義以添加適當的比例和精度,但我們無法更改表中列的順序。爲了做到這一點,我們正在做以下標識在DML操作期間生成錯誤的行

  • 我們所有的數據複製到一個新表EVI
  • 我們設在現有的EVAPP_INTERFACE表中的數字列NULL
  • 我們改變的精度在EVAPP_INTERFACE
  • 我們將數據複製回

當數據被複制回,然而,一些行產生因爲它們超過了新的比例和/或精度設置(即,應該存儲利率的列中的值爲10億)。

ERROR : ORA-01438: value larger than specified precision allowed for this column 

我想確定哪個列和哪些行有這個壞數據。

首先複製表

select count(*) into countTab from USER_TAB_COLUMNS where TABLE_NAME = 'EVI'; 
IF (countTab <> 0) then 
    execute immediate 'drop table EVI'; 
    execute immediate 'create table EVI as (select * from EVAPP_INTERFACE)'; 
ELSE 
    execute immediate 'create table EVI as (select * from EVAPP_INTERFACE)'; 
END IF; 
execute immediate 'TRUNCATE TABLE EVAPP_INTERFACE'; 

然後,我改變精度:有226這樣的塊throughtout腳本。

select count(*) into countCol from USER_TAB_COLUMNS where TABLE_NAME = 'EVAPP_INTERFACE' and COLUMN_NAME = 'PST_NUM' and DATA_SCALE is null; 
    IF (countCol <> 0) then 
execute immediate 'alter table EVAPP_INTERFACE modify PST_NUM NUMBER(14,2)' ; 
    DBMS_OUTPUT.put_line(' EVAPP_INTERFACE.PST_NUM has been modified to the required precision'); 
END IF; 

然後,我插回舊數據。這是它的炸彈

execute immediate 'INSERT INTO EVAPP_INTERFACE SELECT * from EVI'; 

所以,我不能完全肯定,如果SQLERRM和SQLCODE將給予充分的堆棧跟蹤。而且,我沒有足夠的數據集來驗證這一點。任何人都可以確認,無論如何,我可以找出哪個特定列導致問題?我已經提供了NUMBER(14,2)作爲大多數列的精度,並且如果可能的話,我想擦除不良數據而不是提高精度。由於它是生產數據,我不允許導入數據來檢查它。

回答

1

您可能想要使用DML Error Logging來記錄所有有問題數據的行。

我不確定爲什麼你要在任何地方使用動態SQL--在腳本之外創建表格會更傳統,而不是每次都刪除&。這將允許您使用靜態SQL來引用表,並且可以讓您將大量錯誤檢查移入編譯階段而不是執行階段。不過,我認爲你有充分的理由要求這是完全動態的。

您需要創建一個錯誤表(如果您要刪除基表以便重新創建,您需要刪除錯誤表)。而且您需要修改INSERT才能添加LOG ERRORS INTO。像

dbms_errlog.create_error_table('EVAPP_INTERFACE', 
           'EVAPP_ERROR'); 

東西創建錯誤表和

EXECUTE IMMEDIATE 
    'INSERT INTO evapp_interface ' || 
    ' SELECT * ' || 
    ' FROM evi ' || 
    ' LOG ERRORS INTO evapp_error ' || 
    ' REJECT LIMIT UNLIMITED'; 

將數據插入到EVAPP_INTERFACE而寫任何故障EVAPP_ERROR(我們在一步創建上述錯誤表)。

+0

是的,這個腳本是部署/升級的一部分,所以錯誤檢查和插入需要同時完成。這是一個了不起的工具,我希望我以前發現過它。但是,我注意到帶有DML錯誤日誌記錄的腳本運行時不考慮錯誤並修改了精度,同時記錄了EVAPP_ERROR中的錯誤。那麼,它是否跳過了有錯誤的行? – roymustang86 2012-07-23 21:12:40

+0

它看起來像從主表中刪除了那些壞行。 – roymustang86 2012-07-23 21:17:31

+0

@ roymustang86 - 將有錯誤的行寫入錯誤表(連同對錯誤的描述),成功插入可成功插入的行。您必須找出解決問題數據的最佳方法,然後您可以重新處理錯誤表中的那些行,或者可以修復源中的數據並重新運行整個轉換。如果您希望在N次失敗後「INSERT」停止處理,您可以指定一個'REJECT LIMIT <>'而不是指定'UNLIMITED' – 2012-07-23 21:22:07

相關問題