2012-04-18 5 views
1

진수입니다. 나는 안전하게 DST_TABLE하는 SRC_TABLE에서 행을 복사해야 안전 주조 VARCHAR 내가이 테이블은 외부 시스템에서 데이터가로드되는 소스 테이블</p> <pre><code>create set table SRC_TABLE ( Some_Id varchar(2O) not null ); </code></pre> <p>이 테라 데이타 DB에서 테라 데이타

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

목표 테이블

있습니다. 외부 시스템이 DECIMAL (4)로 변환 가능한 값만 제공한다는 계약이 있습니다. 그러나 SRC_TABLE에서 계약을 준수하지 않는 행을 선택하는 데 안전한 방법이 있습니까? 그리고 형변환 오류가 발생할 수 있습니까?

업데이트 : 나는 때문에 내가하고 있어요 환경의 제한으로 UDF 기능을 사용할 수 없습니다

답변

0

마지막으로 제 동료의 도움을 받아 실현 가능한 해결책을 찾았습니다. 그것은 약간의 제한이 있습니다 (부호는 고려되지 않습니다. 소수 부분은 고려되지 않습니다). 그러나 ID에 대해서는 잘 작동합니다. 모두 시작과 문자열의 끝에서

  1. 트림 공간 문자열에서
  2. 트림 선행 제로
  3. 이 네 개의 문자 (에 제로와 최대 허용 길이
  4. 패드 문자열
  5. 테스트 문자열의 시작 부분에 네 개의 0을 추가하고 문자열에서 4 자)
  6. 테스트

그래서 기록을 0에서 허용되는 문자 세트에 문자열의 각 위치에 마지막으로 도착 DECIMAL(4)로 변환 할 수 없습니다 1,233,994,는 선택 방법 :

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

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

+0

작업중인 Teradata의 버전은 무엇입니까? –

+0

13.10에서 작업 중입니다. MERGE INTO 문을 사용하여 답변을 업데이트 할 수 있습니까? – JohnyCash

0

당신은 FastExport를 사용하여 이전 테이블에서 데이터를 작성하고 다음 빠른로드를 사용하여 새 테이블에로드 할 수있다. 10 진수 (4, 0)로 구문 분석 된 레코드는 새 테이블에로드되고 나머지는 오류 테이블에 기록됩니다. 소수의 오류 후에 작업이 종료되지 않도록 충분히 높은 ERRLIMIT을 설정하십시오.

+0

팁 주셔서 감사합니다. 불행히도 나는 FastExport/FastLoad를 사용할 수없고 일반 Teradata SQL로 제한되는 DWH 로딩 프로세스의 특정 부분에서이 작업을 수행하고 있습니다. – JohnyCash