2012-11-08 4 views
5

데이터베이스에서 Lämmönmyyntipalvelut이라는 단어를 찾아야합니다. 오직 데이터베이스에서 값이 PHP 배열로 된 필드에 json_encode()를 사용하여 JSON으로 변환되므로 특수 문자가 16 진수 유니 코드로 검색됩니다.MySQL : 유니 코드 엔터티 쿼리

그래서 내 쿼리는

SELECT * FROM table WHERE (services LIKE '%Lämmönmyyntipalvelut%') 

결과가 없습니다. 놀랄 일이 아닙니다.

SELECT * FROM table WHERE (services LIKE '%L\u00e4mm\u00f6nmyyntipalvelut%') 

검색 결과와 그 이유를 궁금해 : 다음, 특수 문자 쿼리가 변환되지 않습니다. 다음으로 특수 문자 만 쿼리를 테스트했습니다.

SELECT * FROM table WHERE (services LIKE '%\u00e4%') 

발견 된 항목을 찾았습니다. 다음으로 나는 물건을 추가하기 시작했다. (처음부터 끝까지) 그것이 잘못되었는지보기 시작했다 :

SELECT * FROM table WHERE (services LIKE '%L\u00e4%') 

결과가 없다. 다른 시험 :

SELECT * FROM table WHERE (services LIKE '%\u00e4mm%') 

발견 된 물건.

내 결론은 백 슬래시가 어떻게 든 엉망으로 만든다는 것이지만 어떻게 이해할 수 있습니까?

편집 : 서비스 분야의

정확한 내용 :

["Neuvonta","L\u00e4mm\u00f6nmyyntipalvelut", 
"Mets\u00e4-\/energiapuunkorjuupalvelut"] 

정확한 쿼리

SELECT id, uid, company_name, services, logo FROM rekisteroeidy_toimijaks 
WHERE 
    (services LIKE '%L\u00e4mm\u00f6nmyyntipalvelut%' AND 
    services LIKE '%Mets\u00e4-\/energiapuunkorjuupalvelut%') 
ORDER BY company_name ASC 

내가 어떤 라인은 가독성을 돕기 위해 중단했다.

+0

'json_encode()'결과를 보여줍니다. –

+0

서비스 필드의 내용을 의미합니까? –

+0

예, 누군가 문제가있는 곳에서 볼 수 있습니다. –

답변

7

는 그 이유를 전혀 생각이 없지만, 트리플 탈출 도움이됩니다!

글쎄, 그건 단지 이중 이스케이프,하지만 네, 그것은 작동하고 여기에 이유 : MySQL은, 당신이 LIKE 연산자를 사용하는 경우 포함 이스케이프의 두 번째 레이어가있다.

services LIKE '%L\\\\u00e4mm\\\\u00f6n%' 

문자 MySQL의 문자열이 당신에게 LIKE 쿼리 %L\\u00e4mm\\u00f6n%과의 비교를 제공한다는 분석.MySQL은 LIKE 쿼리에서 \을 이스케이프로 처리하기 때문에 실제로는 L\u00e4mm\u00f6n을 포함하는 리터럴 문자열과 일치합니다.

이유는 리터럴 % 또는 _ 문자가 포함 된 쿼리 식과 문자열을 비교할 수 있기 때문입니다. 내가 리터럴 문자열 100%에 대한 열을 검색 할 경우 예를 들어, 나는 ('100\\%' 같은 쿼리로 작성) 100\%에 대해 그것을 일치 정말 백퍼센트과 백으로 시작 그냥 임의의 문자열을 얻고 있는지 확인 할 수 있습니다.

MySQL은 LIKE 쿼리 이스케이프와 문자열 리터럴 이스케이프 둘 모두에 백 슬래시를 사용합니다. 특히 실제 인코딩을 사용하는 둘러보기 프로그래밍 언어를 사용하고 있기 때문에 실제 트리플 인코딩으로 끝납니다. "services LIKE '%L\\\\\\\\u00e4mm\\\\\\\\u00f6n%'"처럼 - 아!

이 문제가 ANSI SQL 준수가 아니라고 이중 불행한 주어진, 그리고 다른 데이터베이스에서 작동하지 않습니다. ANSI SQL이 기본적으로 LIKE 쿼리에서 탈출 문자가 없다, 그래서 당신은 _ 리터럴 % 일치 할 경우, 또는 당신이

something LIKE '100=%' ESCAPE '=' 

: 예, 지명하여 자신의 이스케이프 문자를 옵트 인 할 필요가 있다고 데이터베이스 간 호환성을 위해서는 항상 LIKE ... ESCAPE 양식을 사용하고 끔찍한 백 슬래시 이외의 것을 선택하는 것이 가장 좋습니다! (제외 - SQL 문자열 리터럴 이스케이프에 대한 MySQL의의 백 슬래시는하지 ANSI 중 하나를 준수한다 있습니다하지만 당신은 NO_BACKSLASH_ESCAPES의 sql_mode 설정으로 그 잘못된 행동을 해제 할 수 있습니다!.)

은 아마 더 나은 아이디어가 아니라 두 번째 테이블에 밖으로 services를 파괴하는 것입니다 그들을 단일 문자열 열로 스쿼시하는 것보다 - 즉. First Normal Form에 스키마를 넣으십시오. 그런 다음 느린 전체 테이블 스캔 부분 문자열 일치를 수행하지 않고 개별 값을 간단히 조회 할 수 있습니다.

+0

어떤 이유로 내 데이터베이스에서 이스케이프가 전혀 작동하지 않습니다. 바이너리가있는 /없는 모든 조합을 시도하고 1 회에서 8 회 회피.utf8mb4_unicode_ci 데이터 정렬을 사용하여 무언가를해야 할 수도 있습니다. 필자가 예제 작업을 할 수있는 유일한 방법은 다음과 같다. "SELECT * FROM table WHERE BINARY CONCAT ('% L', UNHEX ('c3a4'), 'mm %'); 그렇지 않으면 결과는 a에 분음없는 'Lamm'과 일치합니다. –

+0

@KapiteinWitbaard : 환경에 상관없이'% Lmm % '를 직접 입력 할 수 없다면 실제'ä '문자 (UTF-8 데이터 정렬 가정)와 일치하는 방법 중 하나입니다. 이것은 OP가하는 작업이 아니며, 일부 직렬화 된 JSON에서는 실제 백 슬래시와 일치하도록 시도했지만 문자 적으로는'ä '가 아닙니다. JSON은 유니 코드 문자를 참조하도록'\ uNNNN'을 이스케이프 처리합니다. SQL 리터럴 자체는 그렇지 않습니다. – bobince

+1

@KapiteinWitbaard : 가능하면 '서비스 열'을 비교할 때 사용하려는 데이터 정렬에 저장하는 것이 더 효율적이어야합니다. 정확한 문자와 일치 시키려면'utf8_bin'과 같은'BINARY' 데이터 정렬 일 수도 있습니다; 대/소문자를 구분하지 않고 액센트에 민감한 일치를 원할 경우 기본 정렬 집합의 [놀랍게도 누락 된] (https://bugs.mysql.com/bug.php?id=19567) 조합을 사용해야합니다. 그것 주위. – bobince

3

백 슬래시는 메타 문자이므로 MySQL은 다음 문자를 제거하고 메타 문자로 구문 분석하지 않습니다. , MySQL은

+0

불행하게도, 도움이되지 않습니다. –

+0

정말요? "정확한 쿼리"에서 백 슬래시는 이스케이프 처리되지 않습니다. 이처럼 모든 백 슬래시를 벗어나면 문제가 해결됩니까? : \t 선택 ID, uid, 회사 이름, 서비스, 로고 어디에서 (서비스 '% L \\ u00e4mm \\ u00f6nmyyntipalvelut %'와 같은 서비스와 '% Mets \\ u00e4 - \\/energiapuunkorjuupalutut'와 같은 서비스) ORDER BY company_name ASC – Vince

+0

정말 이상한 소리입니다. 논리적으로 당신의 대답은 좋고 정확하고 이해가되지만, 나는 시도하고 그것이 작동하지 않습니다. –

1
(첫 번째 백 슬래시는 두 번째 탈출하는 데 사용되는 메타 문자) "\"에 의해 "\\"대체합니다 이제

SELECT * FROM table WHERE (services LIKE '%L\\u00e4%') 

:

그래서 당신은 백 슬래시를 이스케이프 할 필요가

나는 왜 모르겠다. 그러나 트리플 탈출가 도움이된다!

SELECT id, uid, company_name, services, logo 
FROM rekisteroeidy_toimijaks 
    WHERE (
    services LIKE '%L\\\\u00e4mm\\\\u00f6n%' 
) 
ORDER BY company_name ASC 
LIMIT 0 , 30 
+1

PHP, java 또는 다른 언어로 작업하는 것처럼 들립니다. 나는 확실히 확신한다, 빈스의 대답은 그것없이 끝났다. 따라서이 경우, [답변을 수락해야합니다] (http://meta.stackexchange.com/a/5235). –

+0

하지만 phpMyAdmin을 사용하여 정확하게 동일한 동작을 수행 할 때 어떻게 사용 언어 (PHP인지, 올바른지)에 의존 할 수 있습니까? –

+0

방금 ​​mysql 명령 줄에서이 방법을 직접 사용해 보았습니다. 나는 혼란에 빠져서 죄송합니다. –

관련 문제