Announcement

Collapse
No announcement yet.

MS-SQL-Server und ungewöhnliches Verhalten bei Like-Abfragen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • MS-SQL-Server und ungewöhnliches Verhalten bei Like-Abfragen

    Folgendes mir unerklärliches Verhalten stelle ich am MS-SQL-Server fest:

    In der Tabelle mytable in der Spalte myCol (nvarchar) ist der Wert '010101'.

    Ich frage die Datenbank mit folgender Query ab:

    exec sp_executesql N'select * from mat where (m_matnr like @P1 )', N'@P1 nvarchar(50)', N'0101%' ( = #$0400).

    Die Abfrage muss mittels exec sp_...-Ausgeführt werden da sonst die Unicode-Zeichen überhaupt nicht durchkommen (anderes "Feature" von MS-SQL).

    Nach meinen Verständnis sollte doch der obige Datensatz nicht als Ergebnis geliefert werden, da das Zeichen #$0400 ja nicht im String '010101' vorhanden ist. Kommt er aber!<br>
    Wird statt #$0400 z.B. E ('0101%E') verwendet, so kommt der Datensatz nicht zurück.

    Gibt es hier noch eine (versteckte) Einstellmöglichkeit um wirklich 100% Unicode-Verhalten beim MS-SQL-Server zu bekommen?

  • #2
    Hallo Bernhard,

    ich kann das Problem beim direkten Hantieren mit T-SQL (Query Analyzer) nicht nachvollziehen (MS SQL Server 2000, Datenbank <i>tempdb</i>):
    <pre>
    <b>CREATE</b> <b>TABLE</b> UnicodeTest
    (
    RecID <b>INTEGER</b> <b>NOT</b> <b>NULL</b> <b>IDENTITY</b> <b>PRIMARY</b> <b>KEY</b>,
    <b>Test</b> NVARCHAR(50) <b>NOT</b> <b>NULL</b>
    )
    <b>GO</b>
    <b>INSERT</b> <b>INTO</b> UnicodeTest (<b>Test</b>) <b>VALUES</b> (N<font color="#9933CC">'010101'</font>);
    <b>INSERT</b> <b>INTO</b> UnicodeTest (<b>Test</b>) <b>VALUES</b> (N<font color="#9933CC">'010101‘'</font>); -- ALT + 0401
    <b>INSERT</b> <b>INTO</b> UnicodeTest (<b>Test</b>) <b>VALUES</b> (N<font color="#9933CC">'010101'</font>); -- ALT + 0400
    <b>GO</b>
    <b>SELECT</b> * <b>FROM</b> UnicodeTest
    <br>
    <b>DECLARE</b> @Param NVARCHAR(50)
    <b>SET</b> @Param = N<font color="#9933CC">'010101%'</font>
    <b>SELECT</b> * <b>FROM</b> UnicodeTest <b>WHERE</b> <b>Test</b> <b>LIKE</b> @Param
    <br>
    RecID <b>Test</b> <br>
    ----------- --------------------------------------------------
    3 010101
    <br>
    (1 <b>row</b>(s) affected)
    <br>
    <b>DELETE</b> <b>FROM</b> UnicodeTest <b>WHERE</b> RecID = 3
    <b>GO</b>
    <br>
    <b>DECLARE</b> @Param NVARCHAR(50)
    <b>SET</b> @Param = N<font color="#9933CC">'010101%'</font>
    <b>SELECT</b> * <b>FROM</b> UnicodeTest <b>WHERE</b> <b>Test</b> <b>LIKE</b> @Param
    <br>
    RecID <b>Test</b> <br>
    ----------- --------------------------------------------------
    <br>
    (0 <b>row</b>(s) affected)
    </pre>
    Über welchen Weg (ODBC, OLE DB) führt das Programm diese Anweisungen aus?

    Auch wenn ich das Konstrukt <i>exec sp_executesql N'select * from UnicodeTest where (Test like @P1 )', N'@P1 nvarchar(50)', N'0101%'</i> im Query Analyzer ausführe, liefert er keinen Treffer zurück, nachdem der dritte Datensatz aus meiner Beispieltabelle gelöscht wurde

    Comment


    • #3
      Hallo Andreas,

      war noch ein kleiner Fehler in Testdaten. Das Problem ist nicht mit #$0400 sondern mit #$0300. :-)

      Ergänze deinen Test um folgende Zeilen

      INSERT INTO UnicodeTest (Test) VALUES (N'010101EÌ'); -- ALT + 0300

      SET @Param = N'010101%Ì'
      SELECT * FROM UnicodeTest WHERE Test LIKE @Param

      Die Abfrage mit #$0300 ergibt 4 Ergebnisdatensätze (also alle Datensätze in unserer Testdatenbank

      Comment


      • #4
        Hallo Bernhard,

        auch mit diesen Daten liefert meine Abfrage nur den passenden Datensatz zurück:
        <pre>
        DECLARE @Param NVARCHAR(50)
        SET @Param = N'010101%Ì'
        SELECT * FROM UnicodeTest WHERE Test LIKE @Param
        <pre>
        Abbildung siehe Anhan

        Comment


        • #5
          Hallo Bernhard,

          auch mit diesen Werten liefert mein Versuch nur den richtigen Treffer zurück (siehe Anhang)

          Comment


          • #6
            Hallo Andreas,

            also irgendwie werden meine Posting-Sonderzeichen umgewandelt. Und du wirst vermutlich über die Zwischenablage den Code einfügen haben. Und dieser ist falsch!!!!!

            INSERT INTO UnicodeTest (Test) VALUES (N'010101EÌ'); <- Das Ì ist <b>nicht</b> #$0300 sondern #$00CC!

            Nochmal mit entsprechender HTML-Codierung:

            INSERT INTO UnicodeTest (Test) VALUES (N'010101E');

            SET @Param = N'010101%'<br>
            SELECT * FROM UnicodeTest WHERE Test LIKE @Param

            So, ich denke jetzt dürte es ein (#$0300) bleiben

            Comment


            • #7
              Hallo Bernhard,

              jetzt kann ich Dein Problem reproduzieren (siehe Anhang). Auf der BOL-Hilfeseite zu LIKE stehen u.a. die beiden folgenden Sätze: "<i>Der Unicode-LIKE-Operator ist mit dem SQL-92-Standard kompatibel. Der ASCII-LIKE-Operator ist mit früheren Versionen von SQL Server kompatibel.</i>". Mit dieser Aussage kann es nur 2 Möglichkeiten geben: <br>
              1. Der MS SQL Server hat einen Bug, oder <br>
              2. Der SQL-92-Standard sieht es darartiges Verhalten vor ;-

              Comment


              • #8
                Hallo Andreas,

                weißt Du wo man den SQL-92-Standard nachlesen kann?

                Hab jetzt auch mal bei MS in der Newsgroup gepostet. Mal sehen was passiert..

                Comment


                • #9
                  Hallo Andreas,

                  im MS-SQL-Server-Forum unter news.microsoft.com konnte mir jemand Helfen:

                  Ursache ist das Sortierverhalten des MS SQL-Servers: (<a href="http://support.microsoft.com/?kbid=305704">PRB: Windows Collations Ignore Single Quote and Hyphen When Ordering</a>.

                  Als Lösung gibt es nur die Möglichkeit entweder bei der Erstellung der Datenbank oder bei den entsprechenden Spalten auf binäre Sortierung umzustellen (COLLATE Latin1_General_BIN

                  Comment


                  • #10
                    Hallo Berhard,

                    das hört sich dann doch schon wieder besser an. Diese Eigenheit scheint in die gleiche Kategorie zu fallen wie die Case-Sensitive WHERE-Abfrage (bei der auch vorher eine temp. VARBINARY-Umwandlung notwendig ist, damit die Schreibweise berücksichtigt wird)

                    Comment

                    Working...
                    X