지정된 로케일과 함께 sqlite3에서 텍스트를 정렬하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/611459

문제

기본적으로 sqlite3는 ASCII 문자로만 정렬됩니다. Google을 보려고 노력했지만 내가 찾은 유일한 것은 콜라이트에 대한 정보였습니다. SQLITE3 만 있습니다 NOCASE, RTRIM 그리고 BIARY 콜라이트. 특정 로케일에 대한 지원을 추가하는 방법? (Rails 응용 프로그램에서 사용하고 있습니다)

도움이 되었습니까?

해결책

sqlite 지원합니다 통합 ICU. readme 파일에 따르면sqlite/ext/icu/README.txt그만큼 sqlite/ext/icu/ 디렉토리에는 SQLITE "ICU"확장자에 대한 소스 코드가 포함되어 있습니다.

1. Features

    1.1  SQL Scalars upper() and lower()
    1.2  Unicode Aware LIKE Operator
    1.3  ICU Collation Sequences
    1.4  SQL REGEXP Operator

다른 팁

Doug Currie 답변을 받아 들였지만 SQLITE3 문서가 매우 이상하기 때문에 "알고리즘"을 추가하고 싶습니다.

좋아, 우리는 SQLITE3를 작동 시켰고 지금 :

  1. SQLITE의 ICU 확장자를 다운로드하십시오

  2. 컴파일 :

    gcc -shared icu.c `icu-config --ldflags` -o libSqliteIcu.so
    

    Linux입니다. 또한 추가 ICU 개발 패키지를 설치해야했습니다.

    sudo apt-get install libicu-dev
    

    64 비트 아키텍처를 작업하고 있으며 오류가 발생합니다. __relocation R_X86_64_32S__ (무엇을 의미하든 :). GCC는 추가를 제안했습니다 -fPIC 옵션을 컴파일하고 도움이되었습니다.

  3. sqlite3을 실행하십시오. 명령으로 확장을로드 할 수 있습니다.

    .load './libSqliteIcu.so'
    

    현재 디렉토리에 있다고 가정하면 전체 경로를 지정할 수도 있습니다.

  4. 새로운 Collation 만들기 :

    SELECT icu_load_collation('pl_PL', 'POLISH');
    

    첫 번째 매개 변수는 원하는 로케일이고 두 번째 매개 변수는 (무엇이든 할 수 있음)입니다.

  5. 이제 우리는 새로운 로케일과 데이터를 정렬 할 수 있습니다.

    SELECT * FROM some_table ORDER BY name COLLATE POLISH;
    

    그리고 그것은 둔감합니다!

ICU 확장을 컴파일 할 여유가 없다면 UDF가 동일하게 수행 할 수 있습니다. PHP/PDO에서 :

$pdo->sqliteCreateFunction('locale',
    function ($data, $locale = 'root')
    {
        static $collators = array();

        if (isset($collators[$locale]) !== true)
        {
            $collators[$locale] = new \Collator($locale);
        }

        return $collators[$locale]->getSortKey($data);
    }
);

예제 사용 :

SELECT * FROM "table" ORDER BY locale("column", 'pt_PT');

나는이 접근법이 기본 확장만큼 효율적일 것으로 기대하지는 않지만 반드시 휴대가 가능합니다.

확장자를 스스로 구축 할 수없는 사람들을 위해 MacOS 및 Linux에서 컴파일 버전을 사용할 수있었습니다. http://files.tempel.org/various/sqlite3icuextention

Intel 32와 64 비트의 Linux 버전은 Ubuntu 16에 구축되었습니다.

일반적으로, 당신은 다른 사람들이 제공하는 컴파일 된 코드를 신뢰해서는 안되지만, 나는 상당히 공개적인 사람입니다. 즉, "나쁜"버전을 제공하면 상당히 위험을 감수 할 것입니다. 그리고 내 서버에 대한 중간의 공격 또는 해킹이 없는지 확인하려면 다음은 3 개의 파일에 대한 MD5 해시입니다.

libSqliteIcu-i386.so = 6decd73f27d9c61243128e798304508f
libSqliteIcu-x86_64.so = b127c8a1f65503c91c61a21732eb11be
sqlite3_icu_extension.dylib = a29d59f6b74e7ef234691729b82da660
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top