Reputation: 493
I want to retrieve rows whose TITLE
field meets some pattern (case-insensitive), and this field contains only non-English letters.
I tried this:
SEARCH * FROM TABLE_NAME WHERE UPPER(column_name) LIKE UPPER('%pattern%');
However, this doesn't work, may be because the table contains only non-English letters.
UPDATE:
Example:
SELECT * FROM PartnersTable WHERE UPPER(TitleColumn) LIKE UPPER('%pattern%');
Where:
TitleColumn
may contain "Газпром", "Лукойл", "Йотафон", "Мечта ювелира",
pattern
may contain "газ", "Ювелир" etc.
Upvotes: 10
Views: 9091
Reputation: 1502
I tried it with using COLLATE NOCASE
added to the column definition. If you are able to do it, then this is the way to go.
What I tested:
CREATE TABLE PartnersTable
(`id` , `TitleColumn` COLLATE NOCASE )
;
Added same data as in your question:
INSERT INTO PartnersTable
(`id`, `TitleColumn`)
VALUES
(1, 'Газпром'), (2, 'Лукойл'), (3, 'Йотафон'), (4, 'Мечта ювелира')
;
Then tried to select it:
select *
from PartnersTable
where TitleColumn like '%Ювелир%'
It works.
Demo here: http://sqlfiddle.com/#!7/ae8f8/2
Edit:
You can also use it with without UPPER
. By default LIKE
is case insensitive.
As per documentation:
Any other character matches itself or it's lower/upper case equivalent (i.e. case-insensitive matching). (A bug: SQLite only understands upper/lower case for ASCII characters. The LIKE operator is case sensitive for unicode characters that are beyond the ASCII range. For example, the expression 'a' LIKE 'A' is TRUE but 'æ' LIKE 'Æ' is FALSE.)."
Demo here: http://sqlfiddle.com/#!7/c9b5d/1
Upvotes: 4
Reputation: 18748
If your data contains only a limited set of international letters, one quick and simple solution is to use replace() to manually change the case of the international letters.
For example in my case, I am expecting only [a-z], [A-Z] and [åäöÅÄÖ]:
// First, use application code to make the search string lowercase.
searchStr = searchStr.toLower();
// The SQLite function lower() will not affect ÅÄÖ, so we need
// to manually replace them with their lowercase versions.
sql = "SELECT * "+
" FROM table1 "+
" WHERE "+
" replace(replace(replace( lower(name) , 'Å','å'), 'Ä','ä'), 'Ö','ö') LIKE ?";
db.prepare(sql, ["%"+searchStr+"%"]);
Upvotes: 0
Reputation: 162
The code is not working because UPPER is working for only ASCII characters(link). To solve this I implemented User-Defined function with BindFunction for .NET as below.
// for System.Data.SQLite
connection.BindFunction(
new SQLiteFunctionAttribute("myupper", 1, FunctionType.Scalar),
(Func<object[], object>)((object[] args) => ((string)((object[])args[1])[0]).ToUpper()),
null);
// for Microsoft.Data.Sqlite
connection.CreateFunction(
"myupper",
(string arg) => (arg).ToUpper());
var command = connection.CreateCommand();
command.CommandText =
@"
SELECT *
FROM PartnersTable
WHERE MYUPPER(TitleColumn) LIKE MYUPPER('%pattern%')
";
command.ExecuteQuery()
However it takes longer to execute the query.
Following links might help too
https://learn.microsoft.com/en-us/dotnet/standard/data/sqlite/user-defined-functions https://learn.microsoft.com/en-us/dotnet/standard/data/sqlite/compare
Upvotes: 3
Reputation: 702
Redifine Like function (This uses the Sqlite .NET wrapper). Also note VB like uses asterisk wildcard. If you want % replace the string or redefine GLOB instead.
public static void OverrideLikeFunction()
{
SQLiteSpace.SQLiteFunction.RegisterFunction(typeof(SQLiteHelper.Ulike));
}
[System.Data.SQLite.SQLiteFunction(FuncType=System.Data.SQLite.FunctionType.Scalar, Name="Like")]
;
Public Class Ulike;
Inherits System.Data.SQLite.SQLiteFunction;
Public Overrides Function Invoke(args() As object) As object;
try
{
if (System.Convert.IsDBNull(args(0)) || System.Convert.IsDBNull(args(1)))
{
return false;
}
return (Microsoft.VisualBasic.CompilerServices.StringType.StrLike(System.Convert.ToString(args(1)).ToUpperInvariant(), System.Convert.ToString(args(0)).ToUpperInvariant(), Microsoft.VisualBasic.CompareMethod.Binary));
}
catch (Exception ex)
{
return null;
}
}
}
Upvotes: 0