在SQLite中,我想区分大小写"SELECT LIKE name"
对正常的拉丁名称可以正常工作,但是当名称使用非拉丁字符的UTF-8时,select将区分大小写,如何使其生效也像拉丁字符一样不区分大小写?不区分大小写utf8 select
p.s.我的SQLite是v3和我用PHP PDO
在SQLite中,我想区分大小写"SELECT LIKE name"
对正常的拉丁名称可以正常工作,但是当名称使用非拉丁字符的UTF-8时,select将区分大小写,如何使其生效也像拉丁字符一样不区分大小写?不区分大小写utf8 select
p.s.我的SQLite是v3和我用PHP PDO
SQLite的你有2种选择:
$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();
使用no-case collation连接,如:LIKE name COLLATE NOCASE
如果你需要非ASCII的部分与外壳折叠进行比较特定的字符,该NOCASE
将无法正常工作,因为SQLite不支持这样的折叠 - 您将不得不使用您选择的Unicode库和sqlite3_create_collation()
来提供自己的排序规则功能。
编辑:同样,这可能是有趣:
的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。
我还写了另外一个版本,做basic和x
和y
值extended romanization,使重音字符将匹配它的重音对应,例如:SELECT 'Á' LIKE 'à%';
。
你可以star the gist来关注偶尔的更新。
根据NOCASE的文档,它只是ASCII;它明确表示它不包括UTF-8。 – borrible 2010-11-26 12:56:58
文档说的是,不属于ASCII **的UTF-8字符**将区分大小写。所以A = a但是Œ!=œ。编辑澄清。 – 2010-11-26 13:04:54