SQLite中的土耳其字符在使用LIKE表达式时

时间:2012-04-27 11:31:11

标签: c# java android sqlite

select *from urunler where musteri like %ir%;

测试数据:

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

返回结果:

Kadir
Demir 

如果使用%İr%那么İrem正在返回但是Kadir和Demir没有返回。其他土耳其人的角色也有同样的问题,但没有任何确切的解决方案。我正在编写单声道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));

用这种方式解决了,还单声道c#'使用了库,这里是我需要做的Android.Database.Sqlite.SQLiteDatabase

4 个答案:

答案 0 :(得分:5)

SQL As Understood By SQLite,“LIKE和GLOB运营商”部分:

  

对于超出ASCII范围的unicode字符,LIKE运算符默认区分大小写。

这意味着“İ”与“i”和“I”不同。

答案 1 :(得分:3)

针对此类问题的一种解决方案是将文本的规范化版本保存到另一列中。在INSERT文本之前,用一些常用字符替换所有特殊字符,并将两个版本放在数据库中。

你的桌子就像那样

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

现在,您可以对规范化列进行LIKE比较,并仍然从数据库中返回实际文本。

SELECT musteri FROM table WHERE musteri_normalized LIKE '%ir%';
-> İrem, Kadir

答案 2 :(得分: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

它在单声道中工作......

答案 3 :(得分:0)

这不是最佳解决方案。但是我创建了一种解决方法来解决此问题。

您可以在这里找到它:http://codelama.com/sqlite-turkce-harf-siralamasi-sqlite-turkish-collation/

由于此解决方案需要名为归类的UTF8CI,因此我也做了一些SQLite Admin。也可以找到here on github

我尝试使用icu,从源代码进行编译等。这对我来说是最简单的解决方案。 希望对您有所帮助。

使其生效的步骤: 1.将此代码添加到名称空间中的任何位置: [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. 在您的program.cs中,在打开第一个表单之前插入以下代码: System.Data.SQLite.SQLiteFunction.RegisterFunction(typeof(SQLiteCaseInsensitiveCollation));

现在,您将拥有土耳其语排序规则。 为了使它起作用,您必须在文本列定义之后添加“ COLLATE UTF8CI”。像这样: CREATE TABLE maytable ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, mytextfield1 TEXT NULL COLLATE UTF8CI, mytextfield2 TEXT)

如果收到“没有此类排序规则:UTF8CI”,请在查询末尾添加“ COLLATE BINARY”。像这样: maytable