2012-04-27 2 views
6
select *from urunler where musteri like %ir%; 

Testdaten:türkische Charakter in SQLite während LIKE-Ausdruck mit

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

Rückkehr Ergebnis:

Kadir 
Demir 

, wenn die Verwendung %İr% dann İrem Rückkehr aber Kadir und Demir nicht zurück. Es gibt dasselbe Problem bei anderen türkischen Charakteren, aber keine genaue Lösung. Ich programmiere 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)); 

auf diese Weise gelöst, sondern auch C# mono ‚die Bibliothek verwenden, ist hier, wie ich Android.Database.Sqlite.SQLiteDatabase tun müssen, um

+0

vielleicht können Sie verwenden: http://stackoverflow.com/questions/3480999/using-collate-in-android-sqlite-locales- is-ignored-in-like-Anweisung – zapl

Antwort

3

Eine Lösung für ein solches Problem besteht darin, eine normalisierte Version des Textes in einer anderen Spalte zu speichern. Bevor Sie INSERT den Text ersetzen Sie alle Sonderzeichen mit einem gemeinsamen Zeichen und legen Sie beide Versionen in der Datenbank.

Ihr Tisch sieht aus wie diese dann

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

Jetzt können Sie LIKE Vergleich auf der normalisierten Spalte verwenden und immer noch den realen Text aus der Datenbank zurück.

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

Von SQL As Understood By SQLite im Abschnitt„Die LIKE und GLOB-Operatoren ":

Der LIKE-Operator unterscheidet standardmäßig Groß- und Kleinschreibung für Unicode-Zeichen außerhalb des ASCII-Bereichs.

Dies bedeutet, dass "©" sich von "i" und "I" unterscheidet.

+0

Zusätzlich, wenn Sie in Groß- oder Kleinbuchstaben vor dem Vergleich gehen, wählen Sie höher - es ergibt weniger Mehrdeutigkeit zB der Deutsch "ss" -> B – Basic

+0

aber er erwartet mindestens Kadir und Demir die sind ascii – waqaslam

+0

@ Waqas Und er bekommt Kadir und Demir, wenn er nach '% ir%' sucht. Aber für SQL 'İ! = I'. Die unspezifische Handhabung von Unicode ist extrem kompliziert und tatsächlich gibt es Probleme, bei denen die Antwort von semantischen Informationen abhängt. – Voo

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 

es in Mono funktioniert ...

+2

Danke danke X 10000 :) Ich würde Ihnen 1000 Stimmen geben, wenn ich kann – Igor