1

Teradata DB にはソース テーブルがあります

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 関数を使用できません。

4

3 に答える 3

0

MERGE INTO適用できなかったレコードを取得するには、エラー テーブルを使用した SQLの操作を使用することをお勧めします。これにより、データをロードし、適用できなかったエラー テーブルのレコードを後処理できます。

また、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;
于 2012-04-18T16:50:12.583 に答える
0

FastExport を使用して古いテーブルからデータを書き出し、FastLoad を使用して新しいテーブルにロードすることができます。decimal(4, 0) に解析されるレコードはすべて新しいテーブルにロードされ、残りはエラー テーブルに書き出されます。ERRLIMITいくつかのエラーでジョブが停止しないように、十分に高い値を設定してください。

于 2012-04-18T23:26:43.957 に答える
-1

最後に、同僚の助けを借りて、実行可能な解決策にたどり着きました。いくつかの制限があります (符号は考慮されず、小数部分は考慮されません) が、ID の場合は問題なく機能します。

  1. 文字列の先頭と末尾の両方からスペースを削除
  2. 文字列から先頭のゼロを削除
  3. 最大許容長のテスト
  4. 文字列に 0 を 4 文字まで埋め込む (文字列の先頭に 4 つのゼロを追加し、文字列から最後の 4 文字を取得する)
  5. 許可された文字のセットで文字列の各位置をテストします

SRC_TABLEしたがって、変換できないレコードはDECIMAL(4)select で取得できます。

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');

編集:より便利なのは、変換 char から int TeraData Sql への回答で dnoeth が提案した方法で、TD 13.10 でも機能します。

-- TO_NUMBER returns NULL when failing

CAST(TO_NUMBER(UTENTE_CD) AS INTEGER)

-- check if there are only digits
CASE WHEN UTENTE_CD  = ''                     -- all spaces
       THEN NULL
     WHEN LTRIM(UTENTE_CD, '0123456789') = '' -- only digits
       THEN CAST(UTENTE_CD AS INTEGER)
     ELSE NULL
END
于 2012-04-19T10:40:29.543 に答える