가능한 인코딩 목록에서 Oracle VARCHAR2 값을 UTF-8로 변환하려면 어떻게 해야 합니까?
기존의 이유로 Oracle 10 데이터베이스에는 VARCHAR2 열이 있습니다. 여기서 문자 인코딩은 다음과 같이 설정됩니다.AL32UTF8
일부 UTF-8이 아닌 값을 포함합니다.값은 항상 다음 문자 집합 중 하나에 있습니다.
- US-ASCII
- UTF-8
- CP1252
- 라틴어-1
데이터베이스 외부의 깨진 값을 수정하기 위해 Perl 함수를 작성했습니다.이 데이터베이스 열의 값에 대해 이 인코딩 목록을 루프하고 UTF-8로 변환을 시도합니다. 변환에 실패하면 다음 인코딩을 시도합니다.오류 없이 가장 먼저 전환하는 것은 우리가 유지하는 가치입니다.이제 데이터베이스 내부에 이 기능을 복제하여 누구나 사용할 수 있도록 하겠습니다.
그러나 이를 위해 찾을 수 있는 것은 기능뿐인데, 이 기능은 절대 실패하지 않지만 인식하지 못하는 문자에 대한 대체 문자를 삽입합니다.그래서 내가 아는 한 언제 전환이 실패했는지 알 방법이 없습니다.
이를 위해 두 가지 질문이 있습니다.
- 문자열을 인코딩 목록 중 하나로 변환하여 성공한 첫 번째 인터페이스를 반환하는 기존 인터페이스가 있습니까?
- 그리고 그렇지 않다면 문자열을 인코딩으로 변환할 수 없는 경우 실패를 나타내는 다른 인터페이스가 있습니까?그렇다면 이전 기능을 작성할 수 있습니다.
업데이트:
참고로 이 Postgre를 작성했습니다.PL/pgSQL의 SQL 기능은 내가 필요로 하는 것을 정확하게 수행합니다.
CREATE OR REPLACE FUNCTION encoding_utf8(
bytea
) RETURNS TEXT LANGUAGE PLPGSQL STRICT IMMUTABLE AS $$
DECLARE
encoding TEXT;
BEGIN
FOREACH encoding IN ARRAY ARRAY[
'UTF8',
'WIN1252',
'LATIN1'
] LOOP
BEGIN
RETURN convert_from($1, encoding);
EXCEPTION WHEN character_not_in_repertoire OR untranslatable_character THEN
CONTINUE;
END;
END LOOP;
END;
$$;
오라클에서 이와 동등한 작업을 수행하는 방법을 알고 싶습니다.
@collapsar의 UTF-8의 불법 캐릭터에 대한 주요 정보와 동료가 파헤친 정보 덕분에 다음과 같이 생각해 냈습니다.
CREATE OR REPLACE FUNCTION reencode(string IN VARCHAR2) RETURN VARCHAR2
AS
encoded VARCHAR2(32767);
type array_t IS varray(3) OF VARCHAR2(15);
array array_t := array_t('AL32UTF8', 'WE8MSWIN1252', 'WE8ISO8859P1');
BEGIN
FOR I IN 1..array.count LOOP
encoded := CASE array(i)
WHEN 'AL32UTF8' THEN string
ELSE CONVERT(string, 'AL32UTF8', array(i))
END;
IF instr(
rawtohex(
utl_raw.cast_to_raw(
utl_i18n.raw_to_char(utl_raw.cast_to_raw(encoded), 'utf8')
)
),
'EFBFBD'
) = 0 THEN
RETURN encoded;
END IF;
END LOOP;
RAISE VALUE_ERROR;
END;
신기하게도 WE8까지는.ISO8859P1: WE8MSWIN1252는 제가 가지고 있는 800여개의 나쁜 값들의 목록들을 불만없이 전부 변환합니다.Perl 또는 Postgre의 경우에도 동일하지 않습니다.SQL 구현: 일부 값의 경우 CP1252는 실패하지만 ISO-8859-1은 성공합니다.그래도 오라클에서 나온 값이 적절한 것 같고 유효한 유니코드인 것 같습니다(Postgre에 로드하여 테스트함).SQL), 그래서 불평할 수 없습니다.이 정도면 제 데이터를 소독할 수 있을 것 같습니다.
데이터베이스 열에 잘못된 utf-8이 포함되어 있는지 확인하려면 다음 쿼리를 사용합니다.
select CASE
INSTR (
RAWTOHEX (
utl_raw.cast_to_raw (
utl_i18n.raw_to_char (
utl_raw.cast_to_raw ( <your_column> )
, 'utf8'
)
)
)
, 'EFBFBD'
)
WHEN 0 THEN 'OK'
ELSE 'FAIL'
END
from <your_table>
;
당신의 db charset이 al32utf8임을 감안하면.
라는 점에 주목합니다.EF BF BD
utf-8에서 잘못된 인코딩을 나타냅니다.
표시한 다른 모든 문자 집합이 바이트 중심이므로 유니코드로의 변환은 실패하지 않지만 다른 코드 포인트를 생성할 수도 있습니다.상황 정보가 없으면 실제 소스 문자 집합을 자동으로 결정할 수 없습니다.
잘부탁드려요, 카스텐
문자 ps: :CP1252
->WE8MSWIN1252
LATIN-1
->WE8ISO8859P1
언급URL : https://stackoverflow.com/questions/12717363/how-can-i-convert-oracle-varchar2-values-to-utf-8-from-a-list-of-possible-encodi
'code' 카테고리의 다른 글
AngularJS - HTML의 호출 함수 (0) | 2023.10.10 |
---|---|
MySQL 데몬 잠금 문제 (0) | 2023.10.10 |
함수 내부에서 이 setInterval을 지우려면 어떻게 해야 합니까? (0) | 2023.10.10 |
XML 특성 값의 줄 바꿈이 허용됩니까? (0) | 2023.10.10 |
ASP.IIS 7에서 웹 서비스를 실행하는 사용자 계정은 무엇입니까? (0) | 2023.10.10 |