7
select *from urunler where musteri like %ir%;

test data:

+---musteri---+---ID--+
+-------------+-------+ 
+---İrem------+---1---+ 
+---Kadir-----+---2---+ 
+---Demir-----+---3---+ 

returning result:

Kadir
Demir 

if use %İr% then İrem is returning but Kadir and Demir not returning. There same problem in other turkish characters, but not any exact solution. I am programming mono android.


    [SQLiteFunction(Name = "TOUPPER", Arguments = 1, FuncType = FunctionType.Scalar)]
    public class TOUPPER: SQLiteFunction
    {
        public override object Invoke(object[] args)
        {
            return args[0].ToString().ToUpper();
        }
    }       

    [SQLiteFunction(Name = "COLLATION_CASE_INSENSITIVE", FuncType = FunctionType.Collation)]
    class CollationCaseInsensitive : SQLiteFunction {
        public override int Compare(string param1, string param2) {
            return String.Compare(param1, param2, true);
        }
    }       

TOUPPER.RegisterFunction(typeof(TOUPPER));

solved in this way, but also mono c # 'using the library, here is how I need to do Android.Database.Sqlite.SQLiteDatabase

CL.
  • 158,085
  • 15
  • 181
  • 214
mcxxx
  • 584
  • 1
  • 7
  • 21
  • maybe you can use that: http://stackoverflow.com/questions/3480999/using-collate-in-android-sqlite-locales-is-ignored-in-like-statement – zapl Apr 27 '12 at 11:40

4 Answers4

4

From SQL As Understood By SQLite, section "The LIKE and GLOB operators":

The LIKE operator is case sensitive by default for unicode characters that are beyond the ASCII range.

This means that "İ" is different from "i" and "I".

gfour
  • 918
  • 6
  • 9
  • In addition, if you're going to uppercase or lowercase before comparison, choose upper - it results in less ambiguity eg the germannic "ss" -> B – Basic Apr 27 '12 at 11:38
  • but he's expecting at least Kadir and Demir which are ascii – waqaslam Apr 27 '12 at 11:39
  • 1
    @Waqas And he gets Kadir and Demir if he's searching for `%ir%`. But for SQL `İ != i` . Case insensitive handling of unicode is extremely complicated and in fact there are problems where the answer depends on semantic information. – Voo Apr 27 '12 at 11:40
  • ohh yeah, my mistake... its kinda hard to read that funky **i**. +1 for you :) – waqaslam Apr 27 '12 at 11:45
  • 1
    AFAIK: In turkish `i` is simply not a lowercase `I` because : `i` / `İ` and `ı` / `I` are the corresponding characters. @Basic the german lowercase `ß` corresponds to `SS` (`SZ` in some cases) uppercase since there is no uppercase version of that character. – zapl Apr 27 '12 at 11:50
  • @zapl: There is an uppercase version of ß, namely ẞ, but it is rarely used. – jarnbjo Apr 27 '12 at 12:25
  • 1
    @jarnbjo Don't tell anyone that that letter exists! :) It is so far not part of any official german orthographic rules / alphabet and only exists as Unicode character. – zapl Apr 27 '12 at 13:05
  • The question is asking clearly about another case. In Turkish lower/upper i/İ and ı/I. As I see ICU extension is for that https://www.sqlite.org/cgi/src/dir?ci=6cb537bdce85e088&name=ext/icu – twister Feb 18 '21 at 18:31
3

One solution for such a problem is to saved a normalized version of the text into another column. Before you INSERT the text you replace all special characters with some common character and put both versions in the database.

Your table looks like that then

ID   musteri     musteri_normalized
---  ----------  ------------------
1    İrem        Irem              
2    Kadir       Kadir             
3    yapılcağ    yapilcag 

Now you can use LIKE comparison on the normalized column and still return the real text from the database.

SELECT musteri FROM table WHERE musteri_normalized LIKE '%ir%';
-> İrem, Kadir
zapl
  • 60,293
  • 10
  • 115
  • 141
3
public class Sqlite_DB
{   
    private SqliteConnection CON;
    public  SqliteCommand COM;



    string dbName = System.IO.Path.Combine(@"sdcard", @"testDB.db3");

    public Sqlite_DB()
    {
        TOUPPER.RegisterFunction(typeof(TOUPPER));
        CollationCaseInsensitive.RegisterFunction(typeof(CollationCaseInsensitive));
        CON=new SqliteConnection(String.Format("Data Source={0};Pooling={1}", dbName, false));
        COM=new SqliteCommand(CON);

    }
    public void close()
    {
        COM.Clone();
        CON.Clone();
    }
    public void open()
    {
        CON.Open();
    }

}

#region TOUPPER
[Mono.Data.Sqlite.SqliteFunction(Name = "TOUPPER", Arguments = 1, FuncType = FunctionType.Scalar)]
public class TOUPPER: Mono.Data.Sqlite.SqliteFunction
{
    public override object Invoke(object[] args)//characters for the growth of
    {
        return args[0].ToString().ToUpper();
    }
}       

[Mono.Data.Sqlite.SqliteFunction(Name = "COLLATION_CASE_INSENSITIVE", FuncType = FunctionType.Collation)]
class CollationCaseInsensitive : Mono.Data.Sqlite.SqliteFunction
{
    public override int Compare(string param1, string param2) //According to Turkish character sorting to patch
    {
        return String.Compare(param1, param2, true);
    }
} 
#endregion







public class TEST_X
{
    string strValue="ir";//test
    public void MUSTERI()
    {
        string srg="select * from "+Cari_._
                +"where TOUPPER(musteri) like '%"+strValue.toUpper()+"%';";

        try {
            Sqlite_DB d=new Sqlite_DB();
            d.open();

            d.COM.CommandText=srg;

            SqliteDataReader dr=d.COM.ExecuteReader();

            while (dr.Read()) 
            {

                Android.Util.Log.Error(">>>>",dr[0].ToString()+"<<<");

            }
            d.close();

        } catch (Exception ex) {
            Android.Util.Log.Error(">>>>",ex+"<<<");
        }

    }
}


ID   musteri    
---  ---------- 
1    İrem                   
2    Kadir                   
3    Demir

returning result:

-İrem

-Kadir

-Demir

it works in mono ...

mcxxx
  • 584
  • 1
  • 7
  • 21
0

It is not the best solution. But i have created a workaround to solve this problem.

You can found it here: http://codelama.com/sqlite-turkce-harf-siralamasi-sqlite-turkish-collation/

Because of this solution needs UTF8CI named collation, i also make a little SQLite Admin. It also can be found here on github

I tried to use icu, compiling from source etc. This was the simplest solution for me. I hope it helps.

Steps to make it work: 1. Add this code anywhere in you namespace: [SQLiteFunction(FuncType = FunctionType.Collation, Name = "UTF8CI")] public class SQLiteCaseInsensitiveCollation : SQLiteFunction { private static readonly System.Globalization.CultureInfo _cultureInfo = System.Globalization.CultureInfo.CreateSpecificCulture("tr-TR"); public override int Compare(string x, string y) { return string.Compare(x, y, _cultureInfo, System.Globalization.CompareOptions.IgnoreCase); } }

  1. In your program.cs, just before open first form insert this code: System.Data.SQLite.SQLiteFunction.RegisterFunction(typeof(SQLiteCaseInsensitiveCollation));

Now, you will have Turkish collation. To make this working, you have to add "COLLATE UTF8CI" after your text column definition. Like this: CREATE TABLE maytable ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, mytextfield1 TEXT NULL COLLATE UTF8CI, mytextfield2 TEXT)

If you receive "No such collation: UTF8CI", add "COLLATE BINARY" to the end of query. Like this: select * from mytable order by mytextfield COLLATE BINARY

CoolWolf
  • 1
  • 3
  • 2
    A link to a solution is welcome, but please ensure your answer is useful without it: [add context around the link](https://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers/8259#8259) so your fellow users will have some idea what it is and why it’s there, then quote the most relevant part of the page you're linking to in case the target page is unavailable. [Answers that are little more than a link may be deleted.](https://stackoverflow.com/help/deleted-answers) – Dwhitz Mar 27 '19 at 14:03
  • sorry. i just mind to help the question. is it okay now? i do not always have time to write detailed explanation. So details are already exist on the given link. This is a solution too. What i did now is write all again here. Time is money friend. – CoolWolf Mar 28 '19 at 15:49
  • 1
    Your answer should help people, not your wallet. If you do not have time to write an helpful answer you can skip it. A bad answer some time is worst than have no aswer. Please read [How do I write a good answer](https://stackoverflow.com/help/how-to-answer) – Dwhitz Mar 29 '19 at 07:22
  • Dear Dwhitz, i share solutions on my own blog for more than 10 years. I did not earn single cent in this time. So i never think about money when sharing solutions. This answer here is just to help other peoples. Because i am working with SQLite for many years. I do not know any other solution for Turkish Collation. This is why i decide to write an answer. So i really understand why you warn me. Thanks for that. I understand the answers must give more info instead of links to other sites. I hope the answer helps other users. – CoolWolf Mar 30 '19 at 08:36