none
Case Insensitive Suche über "like" mit UTF-8 in Datenbank mit Umlautproblemen RRS feed

  • Frage

  • Hallo SQLServer Gemeinde,

    in meiner Datenbank werden mit UTF-8 Zeichensatz Daten gespeichert.

    Bei der Suche Bspw wird alles gefunden - egal ob Groß oder Kleinschreibung

    select * from TABLE where FELD like '%"& variable &"%'

    Ist ein der Datenbank ein Umlaut in UTF-8 gespeichert, erhält man nur einen Treffer, wenn man dies korrekt eingibt:

    Beispiel: in Datenbank: MÜLLER > suche nach "müller" kein Treffer > Suche nach "mÜller" oder "MÜLLER" ergibt einen Treffer.

    Die Werte sind in varchar gespeichert.

    Die Seiten werden durch folgenden Code in UTF-8 kodiert:

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    Hat jemand eine Lösung für dieses Problem?

    Vielen Dank für Eure Antworten!

    Samstag, 25. April 2015 15:32

Antworten

Alle Antworten

  • Hi,

    für UTF-8 Inhalte ist nvarchar IMO die sinnvollere Variante. Ansonsten wirst Du irgendwann auf Probleme bei der Speicherung richtiger Sonderzeichen stoßen.

    Poste bitte mal die Sortierung der Tabelle bzw. der betreffenden Spalte.

    Rechte Maustaste auf die Tabelle -> Eigenschaften -> "Erweiterte Eigenschaften" -> "Sortierung"

    Für die Spalte: Tabellenentwurf anzeigen lassen -> Spalte auswählen -> Wert in "Tabellen-Designer" -> Sortierung

    Für einen Test probier mal dieses Statement:

    SELECT * FROM <Tabelle> WHERE <Spalte> LIKE '%ü%' COLLATE Latin1_General_CI_AS

    Und bitte lass den Quatsch, SQL Statements mittels Stringverkettung aufzubauen. Dafür gibt es Parameter. Ich denke mal, dass Du das in VB.NET machst?

    Dim SqlStatement As String = "SELECT * FROM <Tabelle> WHERE <Spalte> = @Wert"
    Dim SqlCommand   As New SqlCommand ( SqlStatement, <Connection> )
        SqlCommand.Parameters.AddWithValue( "@Wert1", "Suchwert" )
    

    Bei LIKE geht das auch, Du musst dann nur die Wildcardzeichen in den Suchbegriff einbinden:

    Dim SqlStatement As String = "SELECT * FROM <Tabelle> WHERE <Spalte> LIKE @Wert"
    Dim SqlCommand   As New SqlCommand ( SqlStatement, <Connection> )
        SqlCommand.Parameters.AddWithValue( "@Wert1", String.Format( "%{0}%", "Suchwert" ) )


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Samstag, 25. April 2015 16:07
    Moderator
  • Hatte mich verschrieben, die Daten sind in nvarchar gespeichert.

    Habe es probiert:

    SELECT * FROM <Tabelle> WHERE <Spalte> LIKE '%ü%' COLLATE Latin1_General_CI_AS or <Spalte2> LIKE '%ü%' COLLATE Latin1_General_CI_AS

    Kein Erfolg!

    Auch mit:

    SELECT * FROM <Tabelle> WHERE <Spalte> LIKE '%ü%' COLLATE SQL_Latin1_General_CP1_CI_AI or <Spalte2> LIKE '%ü%' COLLATE SQL_Latin1_General_CP1_CI_AI

    nicht!

    Case Sensitive funktioniert mit normalen Zeichen, nur mit Umlauten nicht. Was mache ich falsch?

    Samstag, 25. April 2015 16:27
  • Hatte mich verschrieben, die Daten sind in nvarchar gespeichert.

    Habe es probiert:

    SELECT * FROM <Tabelle> WHERE <Spalte> LIKE '%ü%' COLLATE Latin1_General_CI_AS or <Spalte2> LIKE '%ü%' COLLATE Latin1_General_CI_AS

    Kein Erfolg!

    Auch mit:

    SELECT * FROM <Tabelle> WHERE <Spalte> LIKE '%ü%' COLLATE SQL_Latin1_General_CP1_CI_AI or <Spalte2> LIKE '%ü%' COLLATE SQL_Latin1_General_CP1_CI_AI

    nicht!

    Case Sensitive funktioniert mit normalen Zeichen, nur mit Umlauten nicht. Was mache ich falsch?

    Die Spalteneingenschaft ist: Latin1_General_CI_AS

    Es handelt sich um einen SQL Server 2008 Standard

    Samstag, 25. April 2015 16:31
  • die Daten sind in nvarchar gespeichert.

    Also als Unicode; dann solltest Du auch beim Suchstring das Unicode Literal N mit angeben, sonst hast Du da einen ASCII String =>

    SELECT * FROM <Tabelle> WHERE <Spalte> LIKE N'%ü%' ...

    Oder noch besser wie von Stefan mit Parametern arbeiten, dann nimmt Ado.Net Dir die Arbeit ab.


    Olaf Helper

    [ Blog] [ Xing] [ MVP]

    Sonntag, 26. April 2015 05:33
  • Hallo Olaf, Stefan,

    ich habe keine .NET Anwendung sondern eine classic ASP Anwendung.

    habe probiert mit:

    SELECT * FROM <Tabelle> WHERE <Spalte> COLLATE Latin1_General_CI_AS LIKE N'%ü%' or <Spalte2> COLLATE Latin1_General_CI_AS LIKE N'%ü%' 
    
    SELECT * FROM <Tabelle> WHERE <Spalte> COLLATE Latin1_General_CI_AS LIKE N'%"& suchvariable &"%' or <Spalte2> COLLATE Latin1_General_CI_AS LIKE N'%"& suchvariable &"%'
    
    SELECT * FROM <Tabelle> WHERE <Spalte> LIKE N'%ü%' or <Spalte2> LIKE N'%ü%' 
    
    SELECT * FROM <Tabelle> WHERE <Spalte LIKE N'%"& suchvariable &"%' or <Spalte2> LIKE N'%"& suchvariable &"%'

    probiert.

    In der Datenbank ist ein großes Ü -> Suche nach großem Ü geht immer. Ist in der Suche ein kleines ü -> kein Treffer.

    Wenn ich mit dem Literal "N" den Suchstring mir ausgebe, steht immer noch ein "ü" drin (nicht umgewandeltes ü).

    Wo UTF-8 Standard ist, müssten doch alle das Problem haben?!

    Bin dankbar auf Eure Vorschläge.

    PS: folgenden Treiber für die Verbindung verwende ich: Provider=SQLNCLI10

    Sonntag, 26. April 2015 07:49
  • in der Datenbank ist das Ü so gespeichert: Ü
    Sonntag, 26. April 2015 10:39
  • Hallo Michael,

    der SQL Server speichert ausschließlich Unicode (UTF-16) in NVARCHAR (oder aber eine 8-Bit-Sortierung in VARCHAR).

    Du aber hast Du den U-Umlaut als UTF-8 in einer Unicode (UTF-16) Spalte gespeichert - Vergleiche dazu Windows 1252 Code 195 + 156.

    Womit Du "Schrott" in Deiner Datenbank hast, den Du zunächst einmal entsorgen musst - was ein Ersetzen der Umlaute und aller weiteren Sonderzeichen > 128 bedeutet.

    Gruß Elmar

    Sonntag, 26. April 2015 15:44
    Beantworter