2012-02-21 2 views
2

최근 텍스트 파일에서 문자 인코딩이 문자 인코딩으로 잘못 읽히는 문제가 해결되었습니다.이 문제는 파일이 UTF-8인지, Java 코드가이를 열었는지 UTF-8 인코딩의 파일입니다.전체 데이터베이스에서 잘못된 문자 ' ` 검색 - Oracle

그러나 우리는이 �F으로 읽힌 잘못된 문자가 삽입 된 전체 데이터베이스 테이블에 많은 레코드를 추가했습니다. 그래서 우리가 이것을 고쳤다 고해도이 예외를 바로 잡기 위해 지금 데이터베이스 테이블을 정리해야합니다.

누구나이 방법을 제안 할 수 있습니까?

+2

당신이'<< 몇 가지 조건이 문제가 데이터를 표시 <

> FROM 덤프 (<>를, 1016)을 선택하면 >>)'당신이 알고있는 한 테이블의 한 행에 대해 문제가있다. 어떤 이진 값이 문제의 문자로 저장되어 있는가? 당신이 알고있는 몇 가지 다른 경우에 테스트를 반복한다면, 캐릭터는 특정 바이너리 값으로 일관되게 표현됩니까? –

+0

그렇다고 반드시 문자가 왜곡되어있는 것은 아닙니다. 문자를 표시하는 글꼴이 누락되었을 수 있습니다. – Arafangion

+0

@Arafangion : 그건 분명히 사실이 아닙니다. 내가 말했듯이, 수정이 완료되고 새로운 수신 레코드에 대해 특수 문자를 완벽하게 볼 수 있습니다. –

답변

1

나는 비슷한 문제를 가지고있다. 다행히 영향을받는 열의 수가 제한되어 있었고 해당 열은 데이터베이스 전체에서 동일한 이름을 가졌습니다.

나는 다음을 수행 스크립트를 작성하여이 문제를 해결 :

  1. 비활성화 외래 키 제약
  2. 을에
  3. 갱신 모든 테이블을 목표 컬럼을 포함하는 테이블의 목록을 구축하여 REGEXP_REPLACE
  4. 를 이용리스트 데이터가 제약을 다시 활성화 저지

이것은 동적 인 SQL을 사용하여 user_constraintsuser_tab_columns에서 데이터를 가져 와서 내가 목표로 삼았던 특정 열 이름을 필터링했습니다.

다음은 처음 시작하는 데 필요한 거친 골격입니다. 테스트를 거치지 않았으므로 빨리 던져 봤습니다. 당신이 걱정하는 트리거가있는 경우에도, 당신은 너무 사람들을 해제해야합니다 :

-- disable constraints 
BEGIN 
    FOR c IN (
     SELECT c.owner, c.table_name, c.constraint_name, c.constraint_type 
     FROM user_constraints c 
     INNER JOIN user_tables t ON (t.table_name = c.table_name) 
     AND c.status = 'ENABLED' 
     AND c.constraint_type NOT IN ('C', 'P') 
     ORDER BY c.constraint_type DESC 
    ) 
    LOOP 
     dbms_utility.exec_ddl_statement('alter table '||c.table_name||' disable constraint ' || c.constraint_name); 
    END LOOP; 
END; 

-- do the updates 
BEGIN 
    FOR t IN (
     SELECT table_name, column_name 
     FROM user_tab_columns 
     WHERE column_name = 'TEMPERATURE' 
     AND data_type = 'VARCHAR2'; 
    ) 
    LOOP 
     dbms_utility.exec_ddl_statement('UPDATE '||t.table_name||' SET ' ||t.column_name||' = '||''GOOD VALUE''||' WHERE '||t.column_name||' = '||''BAD VALUE''); 
    END LOOP; 
END; 

-- re-enable constraints 
BEGIN 
    FOR c IN (
     SELECT c.owner, c.table_name, c.constraint_name, c.constraint_type 
     FROM user_constraints c 
     INNER JOIN user_tables t ON (t.table_name = c.table_name) 
     AND c.status = 'DISABLED' 
     AND c.constraint_type NOT IN ('C', 'P') 
     ORDER BY c.constraint_type ASC 
    ) 
    LOOP 
     dbms_utility.exec_ddl_statement('alter table '||c.table_name||' enable constraint ' || c.constraint_name); 
    END LOOP; 
END; 
/
+1

'REGEXP_REPLACE를 사용하여 목록의 모든 테이블을 업데이트하면 ' ' 문자가 특정 문자가 아닌 유효하지 않은 코드의 표현이기 때문에 모든 기호를 찾기가 약간 어려울 것입니다 – zerkms

+0

@zerkms 데이터가 처음부터 어떻게 왜곡 될 수 있습니다. *는 유니 코드 프로세서에 의한 유효하지 않은 바이트 시퀀스로 대체되는 문자 인 U + FFFD, "REPLACEMENT CHARACTER"입니다. 따라서 Java가 가져 오기를 망쳐 버리면 Java가 데이터베이스에 넣기 때문에 데이터베이스의 문자로 저장 될 수 있습니다. 데이터가 바이너리 데이터로 데이터베이스에 삽입되고 출력 나사 만 위로 올리면 그 차이가 발생합니다. – deceze

+0

깨진 행을 찾고 대상 열에'DUMP' 함수를 사용하십시오. 이렇게하면 찾고있는'CHAR' 코드를 얻을 수 있습니다. – ninesided

관련 문제