Excel 에서 가져온 일부 데이터가있는 MySQL 데이터베이스를 사용하고 있습니다 . 데이터에는 비 ASCII 문자 (엠 대시 등)와 숨겨진 캐리지 리턴 또는 줄 바꿈이 포함됩니다. MySQL을 사용하여 이러한 레코드를 찾는 방법이 있습니까?
Excel 에서 가져온 일부 데이터가있는 MySQL 데이터베이스를 사용하고 있습니다 . 데이터에는 비 ASCII 문자 (엠 대시 등)와 숨겨진 캐리지 리턴 또는 줄 바꿈이 포함됩니다. MySQL을 사용하여 이러한 레코드를 찾는 방법이 있습니까?
답변:
"ASCII"로 정의하는 것이 정확히 무엇인지에 따라 다르지만 다음과 같은 쿼리 변형을 시도해 보는 것이 좋습니다.
SELECT * FROM tableName WHERE columnToCheck NOT REGEXP '[A-Za-z0-9]';
이 쿼리는 columnToCheck에 영숫자가 아닌 문자가 포함 된 모든 행을 반환합니다. 허용되는 다른 문자가있는 경우 정규식의 문자 클래스에 추가하십시오. 예를 들어 마침표, 쉼표 및 하이픈이 정상이면 쿼리를 다음과 같이 변경합니다.
SELECT * FROM tableName WHERE columnToCheck NOT REGEXP '[A-Za-z0-9.,-]';
MySQL 문서에서 가장 관련성이 높은 페이지는 아마도 12.5.2 정규 표현식 일 것입니다 .
SELECT * FROM tbl WHERE colname NOT REGEXP '^[A-Za-z0-9\.,@&\(\) \-]*$';
MySQL은 이러한 종류의 문제를 해결할 수있는 포괄적 인 문자 집합 관리를 제공합니다.
SELECT whatever
FROM tableName
WHERE columnToCheck <> CONVERT(columnToCheck USING ASCII)
이 CONVERT(col USING charset)
함수는 변환 할 수없는 문자를 대체 문자로 바꿉니다. 그러면 변환 된 텍스트와 변환되지 않은 텍스트가 동일하지 않습니다.
자세한 내용은 이것을 참조하십시오. https://dev.mysql.com/doc/refman/8.0/en/charset-repertoire.html
ASCII 대신 원하는 문자 집합 이름을 사용할 수 있습니다. 예를 들어 코드 페이지 1257 (리투아니아어, 라트비아어, 에스토니아어)에서 올바르게 렌더링되지 않는 문자를 찾으려면CONVERT(columnToCheck USING cp1257)
10 진수 값이 0-127 (0x00-0x7F) 인 모든 문자로 ASCII를 정의하고 다음 쿼리를 사용하여 비 ASCII 문자가있는 열을 찾을 수 있습니다.
SELECT * FROM TABLE WHERE NOT HEX(COLUMN) REGEXP '^([0-7][0-9A-F])*$';
이것은 제가 생각 해낼 수있는 가장 포괄적 인 질문이었습니다.
SELECT * FROM table WHERE LENGTH( column ) != CHAR_LENGTH( column )
'ā'
(바이트 시퀀스로 인코딩 된) UTF-16 열이 있다고 가정합니다. 0x0101
이 테스트를 사용하면 "ASCII"로 간주됩니다 . 거짓 음성 ; 실제로, 일부 문자 집합 내에 있지 인코딩 ASCII 문자를 수행 0x00
하는 0x7f
이 솔루션은 오 탐지를 얻을하곤했다. 이 답변에 의존하지 마십시오!
LENGTH(column)
에 CHAR_LENGTH(column)
관계없이 상수 배수가 됩니다.
이것은 아마도 당신이 찾고있는 것입니다.
select * from TABLE where COLUMN regexp '[^ -~]';
COLUMN에 ASCII가 아닌 문자 (또는 줄 바꿈과 같은 인쇄 할 수없는 ASCII 문자)가 포함 된 모든 행을 반환해야합니다.
정답을 기반으로하지만 ASCII 제어 문자도 고려하면 저에게 도움이 된 솔루션은 다음과 같습니다.
SELECT * FROM `table` WHERE NOT `field` REGEXP "[\\x00-\\xFF]|^$";
동일한 작업을 수행합니다. 열에서 ASCII 범위 위반을 검색하지만 코드 포인트에 대해 16 진수 표기법을 사용하기 때문에 제어 문자도 검색 할 수 있습니다. @Ollie의 답변과 달리 비교 또는 변환이 없기 때문에 이것은 훨씬 더 빠릅니다. (특히 MySQL이 정규식 쿼리에서 조기 종료를 수행하는 경우 확실히해야합니다.)
또한 길이가 0 인 필드를 반환하지 않습니다. 더 나은 성능을 발휘할 수있는 약간 더 긴 버전을 원하면 다음을 대신 사용할 수 있습니다.
SELECT * FROM `table` WHERE `field` <> "" AND NOT `field` REGEXP "[\\x00-\\xFF]";
정규식 패스를 고려하지 않고 길이가 0 인 결과를 피하기 위해 길이에 대한 별도의 검사를 수행합니다. 길이가 0 인 항목의 수에 따라 이것은 훨씬 더 빠를 수 있습니다.
기본 문자 집합이 0x00-0xFF가 ASCII와 동일한 값에 매핑되지 않는 기괴한 경우 (이러한 문자 집합이 어디에나 존재합니까?) 거짓 긍정을 반환합니다. 그렇지 않으면 즐기십시오!
REGEXP
. 따라서 항상 일치하는 것이 보장됩니다. 또한 ^$
당신이 원하는 것이 아닐 수도 있습니다.
Oracle에서는 아래에서 사용할 수 있습니다.
SELECT * FROM TABLE_A WHERE ASCIISTR(COLUMN_A) <> COLUMN_A;
이 질문에 대해 다음 방법을 사용할 수도 있습니다.
SQL 동물원의 질문 :
PETER GRÜNBERG가 수상한 상품에 대한 모든 세부 정보 찾기
비 ASCII 문자
ans : 승자는 'P % GR % _ % berg'와 같은 노벨에서 선택 *;