2010-11-26 119 views
4

在SQLite中,我想區分大小寫"SELECT LIKE name" 對正常的拉丁名稱可以正常工作,但是當名稱使用非拉丁字符的UTF-8時,select將區分大小寫,如何使其生效也像拉丁字符一樣不區分大小寫?不區分大小寫utf8 select

p.s.我的SQLite是v3和我用PHP PDO

回答

5

SQLite的你有2種選擇:

  1. 與ICU支持編譯:How to compileCompilation options
  2. 覆蓋LIKE功能,這裏是一個完整的解決方案(從http://blog.amartynov.ru/?p=675
$pdo = new PDO("sqlite::memory:"); 

# BEGIN 

function lexa_ci_utf8_like($mask, $value) { 
    $mask = str_replace(
     array("%", "_"), 
     array(".*?", "."), 
     preg_quote($mask, "/") 
    ); 
    $mask = "/^$mask$/ui"; 
    return preg_match($mask, $value); 
} 

$pdo->sqliteCreateFunction('like', "lexa_ci_utf8_like", 2); 

# END 

$pdo->exec("create table t1 (x)"); 
$pdo->exec("insert into t1 (x) values ('[Привет España Dvořák]')"); 

header("Content-Type: text/plain; charset=utf8"); 
$q = $pdo->query("select x from t1 where x like '[_РИ%Ñ%ŘÁ_]'"); 
print $q->fetchColumn(); 
2

使用no-case collation連接,如:LIKE name COLLATE NOCASE

如果你需要非ASCII的部分與外殼摺疊進行比較特定的字符,該NOCASE將無法​​正常工作,因爲SQLite不支持這樣的摺疊 - 您將不得不使用您選擇的Unicode庫和sqlite3_create_collation()來提供自己的排序規則功能。

編輯:同樣,這可能是有趣:

How to sort text in sqlite3 with specified locale?

+0

根據NOCASE的文檔,它只是ASCII;它明確表示它不包括UTF-8。 – borrible 2010-11-26 12:56:58

+0

文檔說的是,不屬於ASCII **的UTF-8字符**將區分大小寫。所以A = a但是Œ!=œ。編輯澄清。 – 2010-11-26 13:04:54

1

LIKE的改進版本通過UDF超載:

$db->sqliteCreateFunction('like', 
    function ($pattern, $data, $escape = null) use ($db) 
    { 
     static $modifiers = null; 

     if (isset($modifiers) !== true) 
     { 
      $modifiers = ((strncmp($db->query('PRAGMA case_sensitive_like;')->fetchColumn(), '1', 1) === 0) ? '' : 'i') . 'suS'; 
     } 

     if (isset($data) === true) 
     { 
      if (strpbrk($pattern = preg_quote($pattern, '~'), '%_') !== false) 
      { 
       $regex = array 
       (
        '~%+~S' => '.*', 
        '~_~S' => '.', 
       ); 

       if (strlen($escape = preg_quote($escape, '~')) > 0) 
       { 
        $regex = array 
        (
         '~(?<!' . $escape . ')%+~S' => '.*', 
         '~(?<!' . $escape . ')_~S' => '.', 
         '~(?:' . preg_quote($escape, '~') . ')([%_])~S' => '$1', 
        ); 
       } 

       $pattern = preg_replace(array_keys($regex), $regex, $pattern); 
      } 

      return (preg_match(sprintf('~^%s$~%s', $pattern, $modifiers), $data) > 0); 
     } 

     return false; 
    } 
); 

尊重case_sensitive_like PRAGMA和正確處理x LIKE y ESCAPE z syntax

我還寫了另外一個版本,做basicxyextended romanization,使重音字符將匹配它的重音對應,例如:SELECT 'Á' LIKE 'à%';

你可以star the gist來關注偶爾的更新。