I need to perform a SELECT queries that are insensitive to case and accents. For demo purposes, I create a table like that:
create table table
(
column text collate nocase
);
insert into table values ('A');
insert into table values ('a');
insert into table values ('Á');
insert into table values ('á');
create index table_cloumn_Index
on table (column collate nocase);
Then, I get those results when executing the following queries:
SELECT * FROM table WHERE column LIKE 'a';
> A
> a
SELECT * FROM table WHERE column LIKE 'á';
> á
SELECT * FROM table WHERE column LIKE 'Á';
> Á
How can I fix that so the results for any of the following queries be like that:
> A
> a
> Á
> á
The sqlite is running on iOS, by the way.
Thanks in advance,
You will need to either create some user function, or override (i.e. replace) the default implementation of the like()
functions. The reason is that the LIKE
operator in sqlite doesn't support non-ASCII case-insensitiveness:
SQLite only understands upper/lower case for ASCII characters by
default. The LIKE operator is case sensitive by default for unicode
characters that are beyond the ASCII range. For example, the
expression 'a' LIKE 'A' is TRUE but 'æ' LIKE 'Æ' is FALSE.
This makes sense otherwise sqlite would need to support different cultures since case varies from one to the other. An example is the capital i
in Turkey which is not I
but a dotted İ
, and the lower-case of I
is a dot-less ı
. Embedding all this culture information in sqlite would be very burdensome (i.e. it would increase sqlite object code).
Here is my solution of LIKE problem
static void myLow(sqlite3_context *context, int argc, sqlite3_value **argv)
{
NSString* str = [[NSString alloc] initWithUTF8String:
(const char *)sqlite3_value_text(argv[0])];
const char* s = [[str lowercaseString] UTF8String];
sqlite3_result_text(context, s, strlen(s), NULL);
[str release];
}
// call it once after opening db
sqlite3_create_function(_db, "myLow", 1, SQLITE_UTF8,NULL, &myLow, NULL, NULL);
And then instead of query
SELECT * FROM table WHERE column LIKE 'a'
you should use
SELECT * FROM table WHERE myLow(column) LIKE 'a'