Pergunta

Sqlite3 por padrão classifica apenas por letras ASCII. Eu tentei olhar no google, mas a única coisa que eu encontrei foram informações sobre agrupamentos. Sqlite3 tem apenas NOCASE, RTRIM e BIARY agrupamentos. Como adicionar suporte para um local específico? (Estou usando-o em aplicação Rails)

Foi útil?

Solução

suportes integração com UTI . De acordo com o ficheiro Leia-me, sqlite/ext/icu/README.txt o diretório sqlite/ext/icu/ contém código fonte para o SQLite extensão "UTI", uma integração do "International Components for Unicode" Biblioteca com SQLite.

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

Outras dicas

Eu aceito resposta Doug Currie, mas eu quero adicionar um pouco de "algoritmo" como fazê-lo, porque a documentação sqlite3 é muito estranho (pelo menos para mim).

sqlite3 Ok, temos trabalhando e agora:

  1. Baixar extensão UTI para sqlite

  2. compilá-lo:

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

    É por Linux. Eu também precisava para instalar pacote de desenvolvimento UTI adicional:

    sudo apt-get install libicu-dev
    

    Eu estou trabalhando em arquitetura de 64 bits e eu recebo erro com __relocation R_X86_64_32S__ (seja lá o que significa :). GCC sugeriu a adição de -fPIC de opções de compilação e isso ajudou.

  3. Executar sqlite3. Nós podemos carregar a extensão com o comando:

    .load './libSqliteIcu.so'
    

    Assumindo que está no diretório atual, podemos também especificar o caminho inteiro.

  4. Criar novo agrupamento:

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

    O primeiro parâmetro é desejado local ea segunda é de (pode ser o que for).

  5. Agora podemos classificar os dados com o nosso novo local:

    SELECT * FROM some_table ORDER BY name COLLATE POLISH;
    

    E é caso insensível!

Se você não pode pagar para compilar a extensão UTI pode ter um UDF fazer o mesmo. Em PHP / DOP:

$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);
    }
);

Exemplo de utilização:

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

Eu não espero que esta abordagem para ser tão eficiente quanto a extensão nativa, mas é certamente mais portátil.

Para aqueles que não são capazes de construir a extensão si, eu fiz versões compiladas disponível para MacOS e Linux aqui: http://files.tempel.org/Various/Sqlite3ICUExtention

As versões do Linux, tanto para Intel 32 e 64 bits, foram construídos no Ubuntu 16, se o que importa.

código Geralmente, você não deve confiar compilado fornecido por outros, mas eu sou uma pessoa muito pública, ou seja, eu correria um grande risco se eu fornecer uma versão "ruim". E para ter certeza que não há man-in-the-middle ataque ou hack feito para o meu servidor, aqui estão os hashes MD5 para os 3 arquivos:

libSqliteIcu-i386.so = 6decd73f27d9c61243128e798304508f
libSqliteIcu-x86_64.so = b127c8a1f65503c91c61a21732eb11be
sqlite3_icu_extension.dylib = a29d59f6b74e7ef234691729b82da660
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top