none
Probleme mit LIKE und Wildcard RRS feed

  • Frage

  • Hallo zusammen,

    ich bin über etwas Merkwürdiges im SQL Server 2005 (CompLevel 90) gestolpert und mit meinem Latein am Ende:
    Ich habe ne Tabelle mit einer NVARCHAR(60) NULL Spalten in der ich einen String suche. Wenn ich mit ..LIKE 'TEST123' suche, dann finde ich nichts und muss erst nach ...LIKE 'TEST123%' suchen um den Eintrag zu finden. Erste Idee war eine folgendes Leerzeichen, aber daran lag es nicht (mit LEN() überprüft). Wenn ich eine Testtabelle mit einer Spalte in der Datenbank erstelle, dann funktionieren beide Abfragen. Meine nächste Idee waren die Collations, aber für beide Tabellen wurde nichts angegeben und der DBMS Standard verwendet.

    Es wird aber noch komischer, dass eine andere Datenbank auf dem Server korrekt (bzw. was ich für korrekt halte) funktioniert und ein Backup der auffälligen Datenbank auf einem anderen Server auch nicht so will wie ich (LIKE 'TEST123' oder LIKE 'TEST123%' sollten bei 'TEST123" egal sein).

    Nachtrag:

    Meine neueste Idee ist es, dass (entgegen dem Beispiel) ich nicht nach Buchstaben sondern nach Zahlen suche. Leider hat aber auch ein expliziter Cast nichts gebracht...

    Pascal

    Mittwoch, 27. Oktober 2010 12:50

Antworten

  • Hallo Pascal,

    ich vermute, dass Dich Dein Test auf Leerzeichen in die Irre geführt hat.
    Denn bei LEN werden nachfolgende Leerzeichen nicht berücksichtigt,
    tausche es durch DATALENGTH aus, dort werden die Bytes (und auch Leerzeichen) gezählt.

    Beispiel zur Verdeutlichung:

    CREATE TABLE dbo.Tabelle(
    	id int IDENTITY(1, 1) NOT NULL,
    	Test nvarchar(60) NULL);
    	
    INSERT dbo.Tabelle (Test) VALUES('Test123')
    -- ein Leerzeichen am Ende
    INSERT dbo.Tabelle (Test) VALUES('Test123 ')	
    GO
    SELECT * 
    	, LEN(Test) -- liefert beide Male 7
    	, DATALENGTH(Test) -- Byte-Anzahl (* 2 => Unicode)
    FROM dbo.Tabelle 
    
    -- liefert nur 1. Zeile
    SELECT * FROM dbo.Tabelle
    WHERE Test LIKE 'Test123';
    
    -- liefert beide Zeilen
    SELECT * FROM dbo.Tabelle
    WHERE Test = 'Test123';
    (und mit "=" wäre es nicht passiert)

    Gruß Elmar

    Mittwoch, 27. Oktober 2010 13:57
    Beantworter

Alle Antworten

  • Hallo Pascal,

    ich vermute, dass Dich Dein Test auf Leerzeichen in die Irre geführt hat.
    Denn bei LEN werden nachfolgende Leerzeichen nicht berücksichtigt,
    tausche es durch DATALENGTH aus, dort werden die Bytes (und auch Leerzeichen) gezählt.

    Beispiel zur Verdeutlichung:

    CREATE TABLE dbo.Tabelle(
    	id int IDENTITY(1, 1) NOT NULL,
    	Test nvarchar(60) NULL);
    	
    INSERT dbo.Tabelle (Test) VALUES('Test123')
    -- ein Leerzeichen am Ende
    INSERT dbo.Tabelle (Test) VALUES('Test123 ')	
    GO
    SELECT * 
    	, LEN(Test) -- liefert beide Male 7
    	, DATALENGTH(Test) -- Byte-Anzahl (* 2 => Unicode)
    FROM dbo.Tabelle 
    
    -- liefert nur 1. Zeile
    SELECT * FROM dbo.Tabelle
    WHERE Test LIKE 'Test123';
    
    -- liefert beide Zeilen
    SELECT * FROM dbo.Tabelle
    WHERE Test = 'Test123';
    (und mit "=" wäre es nicht passiert)

    Gruß Elmar

    Mittwoch, 27. Oktober 2010 13:57
    Beantworter
  • Danke sehr. Ich bin parallel drauf gekommen, als ich mir die VarBinarys der Felder angesehen habe und "0200"am Ende fand. In der Doku habe ich mittlerweile gelesen, dass LEN die nachfolgenden Leerzeichen ignoriert und getestet, dass der '=' Operator die auch ignoriert.

     

     

    Nochmals Danke, Pascal.

    Mittwoch, 27. Oktober 2010 14:04