2012-04-18 39 views
1

DECIMAL在Teradata的DB I具有該表被裝入外部系統的數據源表安全鑄造VARCHAR在Teradata的

create set table SRC_TABLE (
    Some_Id varchar(2O) not null 
); 

。我有目標表

create set table DST_TABLE (
    Some_Id decimal(4,0) not null 
); 

我需要將行從SRC_TABLE安全地複製到DST_TABLE。有一個合同到位,外部系統將只提供可轉換爲DECIMAL(4)的值。但是,有沒有安全的方法來選擇SRC_TABLE中不符合合同並可能導致類型轉換失敗的行?

更新:我不能使用UDF功能,由於環境,我在工作的限制

回答

0

最後在同事的幫助下,我找到了可行的解決方案。它有一些限制(不考慮符號,不考慮小數部分),但是對於ID,它工作得很好。

  1. 微調的空間距離都開始和結束字符串
  2. 修剪掉串前導零
  3. 測試的最大允許長度
  4. 墊串用零四個字符(加上四個零字符串的開頭和獲得最後從字符串4個字符)
  5. 測試在字符串中的每個位置上設置允許字符

所以記錄從SRC_TABLE不能轉換爲DECIMAL(4)可以通過選擇來獲得:

select 
    Some_Id 
from 
    SRC_TABLE 
where 
    characters(trim(leading '0' from trim(both ' ' from Some_Id))) > 4 
    or substring(substring('0000' || trim(leading '0' from trim(both ' ' from Some_Id)) FROM characters('0000' || trim(leading '0' from trim(both ' ' from Some_Id))) - 3) FROM 1 FOR 1) NOT IN ('0','1','2','3','4','5','6','7','8','9') 
    or substring(substring('0000' || trim(leading '0' from trim(both ' ' from Some_Id)) FROM characters('0000' || trim(leading '0' from trim(both ' ' from Some_Id))) - 3) FROM 2 FOR 1) NOT IN ('0','1','2','3','4','5','6','7','8','9') 
    or substring(substring('0000' || trim(leading '0' from trim(both ' ' from Some_Id)) FROM characters('0000' || trim(leading '0' from trim(both ' ' from Some_Id))) - 3) FROM 3 FOR 1) NOT IN ('0','1','2','3','4','5','6','7','8','9') 
    or substring(substring('0000' || trim(leading '0' from trim(both ' ' from Some_Id)) FROM characters('0000' || trim(leading '0' from trim(both ' ' from Some_Id))) - 3) FROM 4 FOR 1) NOT IN ('0','1','2','3','4','5','6','7','8','9'); 
+0

做好了解決方案。請注意,雖然它適用於您的特定情況,但它不等同於正確的數字解析器,因爲使用此方法負數和具有小數點的數據將被視爲無效。 – lins314159 2012-04-20 00:07:43

0

我會用在錯誤表的SQL操作MERGE INTO捕捉到了無法應用的記錄表明。這將允許您加載數據並後處理錯誤表中無法應用的記錄。

您也可以從Teradata Developer Exchange下載相應的UDF庫,並使用IsNumeric()等效於對SRC_TABLE的每一行執行條件檢查,以避免將非數字數據插入表中。這種條件檢查可以放棄整個記錄,將記錄加載到日誌表中,或將值設置爲無效數據的約定默認值。

CREATE ERROR TABLE MyDB.TGT_TABLE_ERR FOR MyDB.TGT_TABLE; -- Creates Error Table for MERGE INTO operation 

MERGE INTO MyDB.TGT_TABLE T1 
    USING MyDB.SRC_TABLE T2 
     ON T1.{primary index} = T2.{primary index} 
WHEN MATCHED THEN 
    UPDATE SET Some_ID = CAST(T2.Some_ID AS DECIMAL(4,0)) 
WHEN NOT MATCHED THEN 
    INSERT VALUES (T2.{column list}) 
LOGGING ALL ERRORS WITH NO LIMIT; 
+0

羅布,請你能不能具體談談合併到操作?我搜索了互聯網和Teradata文檔,但沒有發現任何相關信息。不幸的是,由於環境的先決條件,我不能使用UDF庫。 – JohnyCash 2012-04-18 18:02:52

+0

您正在使用什麼版本的Teradata? – 2012-04-18 19:34:19

+0

我在13.10工作。請你能用MERGE INTO語句的例子更新你的答案嗎? – JohnyCash 2012-04-19 07:52:59

0

您可以使用FastExport從舊錶中寫出數據,然後使用FastLoad將其加載到新表中。任何解析爲十進制(4,0)的記錄將被加載到新表中,其餘的將被寫出到錯誤表中。確保設置足夠高的值以確保作業在出現少量錯誤後不會死亡。

+0

感謝您的提示。不幸的是,我在DWH加載過程的某些部分執行此操作,因爲我無法使用FastExport/FastLoad,而且我僅限於普通的Teradata SQL。 – JohnyCash 2012-04-19 10:48:09