Pregunta

Sqlite3 por defecto se ordena solo por letras ascii. Traté de buscar en google, pero lo único que encontré fueron informaciones sobre colaciones. Sqlite3 solo tiene colaciones NOCASE , RTRIM y BIARY . ¿Cómo agregar soporte para un entorno local específico? (Lo estoy usando en la aplicación Rails)

¿Fue útil?

Solución

SQLite admite la integración con UCI . Según el archivo Léame, sqlite / ext / icu / README.txt el directorio sqlite / ext / icu / contiene el código fuente de SQLite " ICU " extensión, un integración de los "Componentes internacionales para Unicode" biblioteca con 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

Otros consejos

Acepté la respuesta de Doug Currie, pero quiero agregar algún "algoritmo". cómo hacerlo, porque la documentación de sqlite3 es muy extraña (al menos para mí).

Ok, tenemos sqlite3 funcionando y ahora:

  1. Descargue la extensión ICU para sqlite

  2. Compilarlo:

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

    Es para Linux. También necesitaba instalar un paquete de desarrollo de ICU adicional:

    sudo apt-get install libicu-dev
    

    Estoy trabajando en una arquitectura de 64 bits y recibo un error con __relocation R_X86_64_32S__ (lo que sea que signifique :). GCC sugirió agregar -fPIC para compilar opciones y ayudó.

  3. Ejecute sqlite3. Podemos cargar la extensión con el comando:

    .load './libSqliteIcu.so'
    

    Suponiendo que está en el directorio actual, también podemos especificar la ruta completa.

  4. Crear nueva clasificación:

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

    El primer parámetro es la configuración regional deseada y el segundo es (puede ser lo que sea).

  5. Ahora podemos ordenar los datos con nuestra nueva configuración regional:

    SELECT * FROM some_table ORDER BY name COLLATE POLISH;
    

    ¡Y no distingue entre mayúsculas y minúsculas!

Si no puede permitirse compilar la extensión ICU, puede hacer que un UDF haga lo mismo. En 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);
    }
);

Ejemplo de uso:

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

No espero que este enfoque sea tan eficiente como la extensión nativa, pero seguramente es más portátil.

Para aquellos que no pueden construir la extensión ellos mismos, he puesto a disposición versiones compiladas para macOS y Linux aquí: http://files.tempel.org/Various/Sqlite3ICUExtention

Las versiones de Linux, tanto para Intel 32 como para 64 bit, se construyeron en Ubuntu 16, si eso es importante.

Generalmente, no debe confiar en el código compilado suministrado por otros, pero soy una persona bastante pública, lo que significa que correría un gran riesgo si proporcionara un '' malo '' versión. Y para asegurarme de que no haya un ataque o pirateo de hombre en el medio en mi servidor, aquí están los hash MD5 para los 3 archivos:

libSqliteIcu-i386.so = 6decd73f27d9c61243128e798304508f
libSqliteIcu-x86_64.so = b127c8a1f65503c91c61a21732eb11be
sqlite3_icu_extension.dylib = a29d59f6b74e7ef234691729b82da660
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top