prosource

비ASC 검색 및 삭제Oracle Varchar2의 II 문자

probook 2023. 2. 22. 22:19
반응형

비ASC 검색 및 삭제Oracle Varchar2의 II 문자

현재 Oracle 데이터베이스 중 하나를 UTF8로 마이그레이션하고 있으며 4000바이트 varchar 제한에 가까운 레코드를 발견했습니다.이러한 레코드를 이행하려고 하면 UF8의 멀티바이트 문자가 포함되어 있기 때문에 실패합니다.PL/SQL 내에서 이러한 문자를 찾아 변경 또는 삭제합니다.

하고 싶은 일은 다음과 같습니다.

SELECT REGEXP_REPLACE(COLUMN,'[^[:ascii:]],'')

그러나 Oracle은 [:asciii:] 문자 클래스를 구현하지 않습니다.

내가 하고 싶은 일을 할 수 있는 간단한 방법이 있나요?

이거면 될 것 같아.

SELECT REGEXP_REPLACE(COLUMN, '[^[:print:]]', '')

「 」를하고 있는 는,ASCIISTR\nnnn , 을 사용할 수 REGEXP_REPLACE★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

UPDATE table SET field = REGEXP_REPLACE(ASCIISTR(field), '\\[[:xdigit:]]{4}', '')

...여기서 필드와 테이블은 각각 필드와 테이블 이름입니다.

프로덕션 코드에 대해서는 권장하지 않지만, 이 방법은 타당하고 효과가 있는 것 같습니다.

SELECT REGEXP_REPLACE(COLUMN,'[^' || CHR(1) || '-' || CHR(127) || '],'')

다음 예시와 같이 선택할 수 있습니다.

select nvalue from table
where length(asciistr(nvalue))!=length(nvalue)  
order by nvalue;

단일 바이트 ASCII 호환 부호화(예를 들어 라틴-1)에서 ASCII 문자는 0 ~127 범위의 바이트일 뿐입니다. 이렇게 '어울릴 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수, 수 등.[\x80-\xFF] 이외의 ASC를 II ★★★

정규 표현을 사용하는 더 직접적인 방법이 있을 거예요.운이 좋으면 다른 사람이 제공해줄 거예요.하지만 매뉴얼을 참조할 필요 없이 할 수 있는 일은 다음과 같습니다.

입력 문자열을 수신하고 varchar2를 반환하는 PLSQL 함수를 만듭니다.

PLSQL 함수에서 입력의 asciistr()을 수행합니다.PLSQL은 4000보다 긴 문자열을 반환할 수 있으며 PLSQL의 varchar2에서 32K를 사용할 수 있기 때문입니다.

이 함수는 비 ASC를 변환합니다.\xxxxx 표기의 II 문자.정규식을 사용하여 검색 및 제거할 수 있습니다.그런 다음 결과를 반환합니다.

다음의 기능도 기능합니다.

select dump(a,1016), a from (
SELECT REGEXP_REPLACE (
          CONVERT (
             '3735844533120%$03  ',
             'US7ASCII',
             'WE8ISO8859P1'),
          '[^!@/\.,;:<>#$%&()_=[:alnum:][:blank:]]') a
  FROM DUAL);

저도 비슷한 문제가 있어서 블로그에 올렸습니다.처음에는 영숫자 정규식으로 시작해서 마음에 드는 몇 개의 기본적인 구두점 문자를 추가했습니다.

select dump(a,1016), a, b
from
 (select regexp_replace(COLUMN,'[[:alnum:]/''%()> -.:=;[]','') a,
         COLUMN b
  from TABLE)
where a is not null
order by a;

1016 배리언트에서는 dump를 사용하여 치환하고 싶은 16진수 문자를 utl_raw.cast_to_varchar2에서 사용할 수 있습니다.

여기서 답을 찾았습니다.

http://www.squaredba.com/remove-non-ascii-characters-from-a-column-255.html

CREATE OR REPLACE FUNCTION O1DW.RECTIFY_NON_ASCII(INPUT_STR IN VARCHAR2)
RETURN VARCHAR2
IS
str VARCHAR2(2000);
act number :=0;
cnt number :=0;
askey number :=0;
OUTPUT_STR VARCHAR2(2000);
begin
str:=’^'||TO_CHAR(INPUT_STR)||’^';
cnt:=length(str);
for i in 1 .. cnt loop
askey :=0;
select ascii(substr(str,i,1)) into askey
from dual;
if askey < 32 or askey >=127 then
str :=’^'||REPLACE(str, CHR(askey),”);
end if;
end loop;
OUTPUT_STR := trim(ltrim(rtrim(trim(str),’^'),’^'));
RETURN (OUTPUT_STR);
end;
/

그런 다음 이 작업을 실행하여 데이터를 업데이트하십시오.

update o1dw.rate_ipselect_p_20110505
set NCANI = RECTIFY_NON_ASCII(NCANI);

다음을 시도해 보십시오.

-- To detect
select 1 from dual
where regexp_like(trim('xx test text æ¸¬è© ¦ “xmx” number²'),'['||chr(128)||'-'||chr(255)||']','in')

-- To strip out
select regexp_replace(trim('xx test text æ¸¬è© ¦ “xmxmx” number²'),'['||chr(128)||'-'||chr(255)||']','',1,0,'in')
from dual

다음과 같은 방법으로 ASCII 이외의 문자가 포함된 열을 검색할 수 있습니다.

select * from your_table where your_col <> asciistr(your_col);

(이 추악한 ORA-31061: XDB 오류: special char to excape char conversion failed를 피하기 위해) 같은 요건이 있었지만 줄 바꿈을 유지해야 했습니다.

좋은 댓글로 해봤는데

'[^ -~|[:space:]]'

ORA-12728: regular expression에 유효하지 않은 범위가 있습니다.

그 결과 해결 방법을 찾을 수 있었습니다.

select t.*, regexp_replace(deta, '[^[:print:]|[:space:]]', '#') from  
    (select '-   <- strangest thing here, and I want to keep line break after
-' deta from dual ) t

(내 TOD 툴에서) 로 표시됩니다.

내 두꺼비 도구에

  • 모든 것을 대체하다^=>는 (인쇄용) 세트에 없습니다.[:print:]또는 스페이스|[:space:]문자)

고마워요, 제 목적에 맞게 작동했네요.그런데 위의 예에서 누락된 단일 따옴표가 있습니다.

REGEXP_REPLACE (COLUMN,'[^' || CHR (32) || '-' || CHR (127) || ']', ' '))

워드랩 기능으로 사용했어요.가끔 들어오는 텍스트에 NewLine/NL/CHR(10)/0A가 포함되어 있어서 일을 망쳤습니다.

Francisco Hayoz의 답변이 최고입니다.sql이 가능한 경우 pl/sql 함수를 사용하지 마십시오.

다음은 Oracle 11.2.03의 간단한 테스트입니다.

select s
     , regexp_replace(s,'[^'||chr(1)||'-'||chr(127)||']','') "rep ^1-127"
     , dump(regexp_replace(s,'['||chr(127)||'-'||chr(225)||']','')) "rep 127-255"
from (
select listagg(c, '') within group (order by c) s
  from (select 127+level l,chr(127+level) c from dual connect by level < 129))

그리고 'rep 127-255'는

타입=1 Len=30: 226,227,228,229,230,231,232,233,234,235,236,237,239,240,241,242,243,245,245,247,247,248,249,250,253,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,255,255,254,254,255,255,255,255,255,255,255,255,25,255,255,255,255,25,14,14,14,14,25

즉, 어떤 이유로든 이 버전의 Oracle은 char(226) 이상을 대체하지 않습니다.'['||chr(127)||-'||chr(225)|||''를 사용하면 원하는 결과를 얻을 수 있습니다.다른 문자를 치환할 필요가 있는 경우는 위의 regex에 추가하거나 치환이 다른 경우는 nested replace|regexp_replace 를 사용합니다(늘 문자열).

사용할 때마다 주의해 주세요.

regexp_like(column, '[A-Z]')

Oracle의 regexp 엔진은 Latin-1 범위의 특정 문자에도 일치합니다.이것은, †->A, ö->O, ü->U 등, ASCII 문자와 유사한 문자에 적용됩니다.따라서 [A-Z]는 Perl 등 다른 환경에서 알 수 없습니다.

문자 세트를 업그레이드하기 전에 정규 표현을 처리하는 대신 NVARCHAR2 데이터 유형을 변경해 보십시오.

또 다른 접근법: 필드의 일부 내용을 잘라내는 대신 데이터베이스에 유럽 문자(즉, 라틴어-1)만 포함되어 있다면 SOUNDEX 기능을 사용해 볼 수 있습니다.또는 Latin-1 범위의 문자를 유사한 ASCII 문자로 변환하는 함수를 작성합니다.

  • > = > a
  • ä = > a
  • ö = > o

물론 UTF-8로 변환되었을 때 4000바이트를 초과하는 텍스트블록에 대해서만 가능합니다.

코멘트 및 코멘트에서 설명한 바와 같이 범위를 사용할 수 있습니다.
오라클 11개

SELECT REGEXP_REPLACE(dummy, '[^ -~|[:space:]]', '?') AS dummy FROM DUAL;

인쇄 가능 범위 외의 것은 물음표로 대체됩니다.

이것은 그대로 실행되므로 설치 시 구문을 확인할 수 있습니다.
dummy ★★★★★★★★★★★★★★★★★」dual원하는 컬럼/테이블을 사용합니다.

이렇게 하면 될 거야.

trim(replace(ntwk_slctor_key_txt, chr(0), ''))

이 질문에 답하는 것은 조금 늦었지만, 최근에도 같은 문제가 있었습니다(사람들은 모든 종류의 것을 잘라서 끈에 붙이고 우리는 그것이 무엇인지 항상 알지 못합니다).다음은 간단한 문자 화이트리스트 접근법입니다.

SELECT est.clients_ref
  ,TRANSLATE (
              est.clients_ref
             ,   'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890#$%^&*()_+-={}|[]:";<>?,./'
              || REPLACE (
                          TRANSLATE (
                                     est.clients_ref
                                    ,'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890#$%^&*()_+-={}|[]:";<>?,./'
                                    ,'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
                                    )
                         ,'~'
                         )
             ,'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890#$%^&*()_+-={}|[]:";<>?,./'
             )
      clean_ref

edms_staging_table est에서

언급URL : https://stackoverflow.com/questions/2236475/finding-and-removing-non-ascii-characters-from-an-oracle-varchar2

반응형