Jak sortować tekst w sqlite3 z podanymi ustawieniami regionalnymi?
Sqlite3 domyślnie sortuje tylko według liter ascii. Próbowałem szukać w google, ale jedyne, co znalazłem, to informacje o kolacjach. Sqlite3 ma tylko NOCASE
, RTRIM
i BIARY
. Jak dodać obsługę konkretnych ustawień regionalnych?
(Używam go w aplikacji Rails)
4 answers
SQLite obsługujeintegrację z ICU. Według pliku Readme,
sqlite/ext/icu/README.txt
katalog sqlite/ext/icu/
zawiera kod źródłowy rozszerzenia SQLite "ICU" ,
integracja biblioteki "International Components for Unicode" z 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-25 17:34:11
Zaakceptowałem odpowiedź Douga Currie 'a, ale chcę dodać jakiś "algorytm" jak to zrobić, ponieważ dokumentacja sqlite3 jest bardzo dziwna (przynajmniej dla mnie).
Ok, mamy działającego sqlite3 i teraz:
-
Skompilować:
gcc -shared icu.c `icu-config --ldflags` -o libSqliteIcu.so
Jest dla Linuksa. Musiałem również zainstalować dodatkowy pakiet programistyczny ICU:
sudo apt-get install libicu-dev
Pracuję na architekturze 64 bitowej i dostaję błąd z
__relocation R_X86_64_32S__
(cokolwiek to znaczy :). GCC zasugerował dodanie-fPIC
do opcji kompilacji i pomogło. -
Uruchom sqlite3. Rozszerzenie możemy załadować poleceniem:
.load './libSqliteIcu.so'
Zakładając, że znajduje się w bieżącym katalogu, możemy również określić całą ścieżkę.
-
Utwórz nowe zestawienie:
SELECT icu_load_collation('pl_PL', 'POLISH');
Pierwszy parametr to pożądane locale, a drugi to it ' s (może być dowolny).
-
Teraz możemy sortować dane z naszym nowym locale:
SELECT * FROM some_table ORDER BY name COLLATE POLISH;
I jest to przypadek nieczułe!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-18 17:42:34
Jeśli nie możesz sobie pozwolić na kompilację rozszerzenia ICU, możesz mieć UDF zrobić to samo. W 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);
}
);
Przykładowe użycie:
SELECT * FROM "table" ORDER BY locale("column", 'pt_PT');
Nie oczekuję, że to podejście będzie tak wydajne jak natywne rozszerzenie, ale na pewno jest bardziej przenośne.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-01 23:59:24
Jak odpowiedział Doug Currie, poprawne porządkowanie znaków akcentowanych można włączyć, ładując rozszerzenie SQLite " ICU "
Rozszerzenie musi zostać skompilowane, jak wyjaśniono w odpowiedzi kiew tutaj. Jednak nazwa biblioteki podana w pliku ICU readme i w odpowiedzi kiew nie zadziałała dla mnie. inna odpowiedź sugerowała użycie nazwy libicu.so
.
Więc to mi się udało Na Ubuntu 16.04 i na Debianie 9.8 Stretch:
sudo apt install libicu-dev libsqlite3-dev dpkg-dev gcc make
apt-get source sqlite3
cd sqlite3-*/ext/icu # assuming you have only 1 sqlite3 source directory
gcc -shared icu.c `icu-config --ldflags` -fPIC -o libicu.so
sudo cp libicu.so /usr/local/lib/
sudo ldconfig
Po tym w sqlite3 możesz
.load libicu
SELECT icu_load_collation('', 'ICU');
Dwa argumenty icu_load_collation
to locale i niestandardowa nazwa. Locale wydaje się być opcjonalne i może być pozostawione puste. Nazwa użytkownika jest wtedy widoczna przez
PRAGMA collation_list;
I może być stosowany jak w
SELECT col FROM tbl ORDER BY col COLLATE ICU;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-17 15:21:03