2009-03-04 20 views
13

Sqlite3 theo mặc định chỉ sắp xếp theo chữ cái ascii. Tôi đã cố gắng tìm trong google, nhưng điều duy nhất tôi tìm thấy là thông tin về collations. Sqlite3 chỉ có NOCASE, RTRIMBIARY đối chiếu. Làm thế nào để thêm hỗ trợ cho một miền địa phương cụ thể? (Tôi đang sử dụng nó trong ứng dụng Rails)Cách sắp xếp văn bản trong sqlite3 với ngôn ngữ được chỉ định?

Trả lời

13

SQLite supports tích hợp với ICU. Theo tệp Readme, sqlite/ext/icu/README.txt thư mục sqlite/ext/icu/ chứa mã nguồn cho phần mở rộng "ICU" SQLite, một tích hợp của thư viện "Thành phần quốc tế cho Unicode" với 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 
+1

Liên kết đầu tiên được bảo vệ bằng mật khẩu ngay bây giờ. –

23

Tôi chấp nhận câu trả lời Doug Currie, nhưng tôi muốn thêm một số thuật toán "" cách thực hiện, vì tài liệu sqlite3 rất lạ (ít nhất là đối với tôi).

Ok, chúng tôi đã sqlite3 làm việc và bây giờ:

  1. Download ICU extension for sqlite

  2. Biên dịch nó:

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

    Nó là dành cho Linux. Tôi cũng cần phải cài đặt thêm gói phát triển ICU:

     
    sudo apt-get install libicu-dev 
    

    Tôi đang làm việc trên kiến ​​trúc 64 bit và tôi nhận được lỗi với __relocation R_X86_64_32S__ (bất cứ điều gì nó có nghĩa :). GCC đã đề xuất thêm -fPIC để biên dịch các tùy chọn và nó đã giúp.

  3. Chạy sqlite3. Chúng tôi có thể tải tiện ích mở rộng bằng lệnh:

     
    .load './libSqliteIcu.so' 
    

    Giả sử rằng nó nằm trong thư mục hiện tại, chúng tôi cũng có thể chỉ định toàn bộ đường dẫn.

  4. Tạo đối chiếu mới:

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

    Tham số đầu tiên là mong muốn và thứ hai là nó (nó có thể là bất cứ điều gì).

  5. Bây giờ chúng ta có thể sắp xếp dữ liệu với ngôn mới của chúng tôi:

     
    SELECT * FROM some_table ORDER BY name COLLATE POLISH; 
    

    Và đó là trường hợp nhạy cảm!

1

Nếu bạn không đủ khả năng để biên dịch phần mở rộng ICU, bạn có thể có UDF cũng làm như vậy. Trong 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); 
    } 
); 

Ví dụ sử dụng:

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

Tôi không mong đợi phương pháp này là hiệu quả như phần mở rộng tự nhiên nhưng nó là xách tay chắc chắn hơn.

Các vấn đề liên quan