Announcement

Collapse
No announcement yet.

SQL Server und Unicode in SELECT Anfrage

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

  • SQL Server und Unicode in SELECT Anfrage

    Hallo zusammen,

    ich habe ein Problem mit SQL-Anfragen auf ein NVarchar Feld (SQL Server 2008 oder auch MSDE), wenn die Abfrage Unicode-Zeichen enthält:

    eine Abfrage der Form:
    Code:
    Select * from unicode_test where value like N'%ۼ%'
    liefert keinen Treffer, wohingehen
    Code:
    Select * from unicode_test where value like '%' + nchar(1788) + '%'
    sehr wohl fündig wird.

    Um das nachzustellen:
    Code:
    create table unicode_test (value NVarChar(20));
    insert into unicode_test values (N'123456ۼ');
    insert into unicode_test values ('XYZ' + nchar(1788) + 'ABC');
    ...
    Das ganze rufe ich per OleDB Provider aus einer Delphi Applikation heraus auf. Was mache ich falsch? Habe mir jetzt schon die Finger wundgegoogelt, ich werde nicht fündig. Hat jemand einen Tipp für mich?
    Vielen Dank,
    Uli

  • #2
    Hallo Uli,

    wenn ich das im SSMS direkt ausführe
    [highlight=SQL]CREATE TABLE #Uni
    (value NVarChar(20));
    GO
    INSERT INTO #Uni VALUES (N'ۼ1234');
    INSERT INTO #Uni VALUES ('XYZ' + nchar(1788) + 'ABC');
    GO
    SELECT *
    FROM #Uni
    WHERE value LIKE N'%ۼ%'
    GO
    DROP TABLE #Uni[/highlight]
    funktioniert es
    [highlight=Text]value
    --------------------
    ۼ1234
    XYZۼABC

    (2 Zeile(n) betroffen)[/highlight]

    Ich tippe mal darauf, das der Unicode auf dem Weg aus Deiner App heraus zum SQL Server hin verloren geht. Allerdings kenne ich Delphi & Co nicht.
    Olaf Helper

    <Blog> <Xing>
    * cogito ergo sum * errare humanum est * quote erat demonstrandum *
    Wenn ich denke, ist das ein Fehler und das beweise ich täglich

    Comment


    • #3
      Hallo Olaf,
      danke für die schnelle Antwort. Jetzt bin ich erstmal platt, dass es bei dir geht - ich hatte das nämlich zuvor auch manuell im SQL Server Management Tool (2008) "per pedes" ausprobiert, und da klappte es auch nicht.

      Meine Vermutung war zunächst auch, dass Unicode irgendwie auf dem Weg von meiner Anwendung zum SQL Server kaputt geht - was mich dann aber wundert ist, dass die INSERT-Kommandos einwandfrei angekommen sind. Die Daten wurden ja aus dem Programm heraus korrekt in die DB eingetragen und können auch über den NCHAR(1788)-Umweg (bzw. ganz ohne WHERE Bedingung) abgefragt werden, d.h. die Unicode-Zeichen kommen schon irgendwie über die Leitung...

      Muss man denn ausser diesem N-Voranstellen bei den String-Konstanten an der Datenbank selbst noch was einstellen?

      Comment


      • #4
        BTW: Füge doch bitte noch eine dritte Zeile in deine Testdaten ein, welche dieses komische Zeichen NICHT enthält. - wird die dann auch korrekt ausgeblendet?

        Comment


        • #5
          Ach so, darauf wolltest Du hinaus ... he he he , wie lustig.
          [highlight=SQL]CREATE TABLE #Uni (value NVarChar(20));
          GO
          INSERT INTO #Uni VALUES (N'ۼ1234');
          INSERT INTO #Uni VALUES (N'XYZ' + nchar(1788) + 'ABC');
          INSERT INTO #Uni VALUES (N'TestTheWest')
          INSERT INTO #Uni VALUES (N'ABC' + nchar(666) + 'XYZ');
          INSERT INTO #Uni VALUES (N'ABC' + nchar(66666) + 'XYZ');
          INSERT INTO #Uni VALUES (N'PLNęPLN')
          GO
          SELECT * FROM #Uni WHERE value LIKE N'%ۼ%'
          SELECT * FROM #Uni WHERE value LIKE N'%' + nchar(1788) + '%'
          SELECT * FROM #Uni WHERE value LIKE N'%' + nchar(666) + '%'
          SELECT * FROM #Uni WHERE value LIKE N'%' + nchar(66666) + '%'
          SELECT * FROM #Uni WHERE value LIKE N'%ę%'
          go
          DROP TABLE #Uni[/highlight]
          [highlight=Text]value
          --------------------
          ۼ1234
          XYZۼABC
          TestTheWest
          ABCʚXYZ
          PLNęPLN

          value
          --------------------
          ۼ1234
          XYZۼABC
          TestTheWest
          ABCʚXYZ
          PLNęPLN

          (5 Zeile(n) betroffen)

          value
          --------------------
          ABCʚXYZ

          value
          --------------------

          (0 Zeile(n) betroffen)

          value
          --------------------
          PLNęPLN

          [/highlight]
          Ein lustiges Ergebnis; habe ich momentan auch keine Erklärung für.
          Olaf Helper

          <Blog> <Xing>
          * cogito ergo sum * errare humanum est * quote erat demonstrandum *
          Wenn ich denke, ist das ein Fehler und das beweise ich täglich

          Comment


          • #6
            Danke für Deine Untersuchungen! :-)
            Auf der einen Seite bin ich ja froh, dass es Dir so ähnlich geht wie mir.
            Andererseits sehr schade, dass Du auch keine Lösung hast :-(
            Das bringt mich noch zur Verzweifelung...

            Comment


            • #7
              Ganz merkwürdig:
              Bis Unicode 1010 (U+03F2 (1010) "ϲ" Griechisches halbmondförmiges Sigma-Zeichen) funktioniert es,
              ab Unicode 1011 (U+03F3 (1011) "ϳ" Griechischer Buchstabe Jot) nicht mehr.
              Also "mitten" drin, nicht mal mit einem Codepage Wechsel oder so

              (und 66666 war natürlich quatsch ;-)
              Olaf Helper

              <Blog> <Xing>
              * cogito ergo sum * errare humanum est * quote erat demonstrandum *
              Wenn ich denke, ist das ein Fehler und das beweise ich täglich

              Comment


              • #8
                Unicode mit Delphi (Verwende D6) + MS SQL Server geht wunderbar. Aber nur sicher und gut durch Verwendeung von parametrisierten Abfragen.

                Dein Problem wird sein das bis D2009 die VCL und die ADOExpress/dbGo-Wrapper noch nicht 100%ig auf Widestrings umgstellt wurden so das ohne parametrisiere Abfragen an der einen oder anderen Stelle Codepagewandlungen zu einem Ansi-String erfolgen.

                Comment


                • #9
                  Hi Bernhard,
                  Danke für den hinweis. Das hätte ich auch vermutet, wenn sich der Effekt nicht im Microsoft SQL Server Management Studio (ganz ohne Delphi und ADO) reproduzieren lässt...
                  Zudem habe ich das ganze aus Delphi heraus auch mal wirklich nur über "Connection.execute(...)" gemacht, da ist das verhalten identisch zu dem im MSSMS.
                  Guck' mal die Antworten weiter oben von Olaf Helper an. Das wundert mich alles sehr.
                  Muss irgend einen anderen Grund haben :-/

                  Ach, und gleich noch etwas: Wenn man über die Spalte einen eindeutigen Schlüssel legt, dann knallt es bei der letzten Zeile mit einer unique key constraint violation... Und nun?

                  Code:
                  CREATE TABLE #Uni (value NVarChar(20));
                  CREATE UNIQUE INDEX idx_v on #Uni(value);
                  INSERT INTO #Uni VALUES (NCHAR(1788) + N'123')
                  INSERT INTO #Uni VALUES (N'1' + NCHAR(1788) + N'23')
                  Zuletzt editiert von audioxp; 08.01.2009, 22:24.

                  Comment


                  • #10
                    ... und wirklich blöde wird es bei
                    Code:
                    CREATE TABLE #Uni (value NVarChar(20));
                    CREATE UNIQUE INDEX idx_v on #Uni(value);
                    INSERT INTO #Uni VALUES (NCHAR(1788) + N'123')
                    INSERT INTO #Uni VALUES (N'1' + NCHAR(1788) + N'23')
                    --> Verletzung des eindeutigen Index...

                    Comment


                    • #11
                      Hast du mal mit dem Tracer kontrolliert was auf DB-Seite ankommt?

                      Comment


                      • #12
                        Naja, wie gesagt, ich habe die letzten Versuche alle direkt im "Microsoft SQL Server Management Studio" selbst ausgeführt. Im Moment mache ich gar nichts mehr mit Delphi, da mir das derzeit alles suspekt ist und ich die Anzahl der Möglichen Fehlerquellen so gering wie möglich halten wollte...

                        Comment


                        • #13
                          Also ich glaube, die Ursache ist gefunden:
                          Wenn man ein "COLLATE Latin1_General_100_CI_AS" an das Ende der Abfragen stellt, werden die richtigen Zeilen gefunden.
                          Bei meiner Datenbank war die Sortierreihenfolge abweichend eingestellt.
                          Dass eine Änderung der Sortierfolge solch komischen Effekte hat, wollte mir erst nicht einleuchten. Aber wenn man sich folgendes Beispiel anschaut:
                          Code:
                          CREATE TABLE Unicode_test (value NVarChar(20));
                          CREATE UNIQUE INDEX idx_v on Unicode_test(value);
                          insert into unicode_test values ('MAßE');
                          insert into unicode_test values ('MASSE');
                          und dann feststellt, dass das einen Indexfehler nach sich zieht, wird es etwas klarer.
                          Meine erfundenen Beispiele waren vermutlich einfach blödsinn...
                          Grüße,
                          Uli

                          Comment


                          • #14
                            An der Stelle hättest Du Elmar Boye ruhig lobend erwähnen dürfen => (microsoft.public.de.sqlserver)

                            Das die Collation einen großen Einfluß hat, ist schon klar

                            CI (Case Insensitive)
                            A = a
                            ß = ss

                            CS (Case Sensitive)
                            A <> a
                            ß = ss

                            AI (Acents Insensitive)
                            A = a
                            ß <> ss

                            AI (Acents Sensitive)
                            A = a
                            ß = ss

                            Nur dieser Break bei 1010 / 1011 leuchtet mir noch nicht ein; vielleicht hatte da an der Stelle jemand keine Lust mehr, die Codepage weiter zu pflegen.
                            Olaf Helper

                            <Blog> <Xing>
                            * cogito ergo sum * errare humanum est * quote erat demonstrandum *
                            Wenn ich denke, ist das ein Fehler und das beweise ich täglich

                            Comment


                            • #15
                              Eine Frage noch an Bernhard Geyer bzgl. der Parametrisierten Anfrage aus Delphi heraus:
                              Wie machst Du das dann mit dem Voranstellen des N bei den Abfragen? Also Select * from #uni where value like N'%123%'
                              Weil wenn Du's parametrisierst, machst Du ja nur
                              sql.text := 'select * from uni where value like aram1'
                              sql.parameters.parambyname('param1').value := '%123';
                              (wenn ich's noch auswendig richtig weiss, mache seit ewigkeiten nix mehr mit parametrisierten queries)
                              Grüße,
                              Uli

                              Comment

                              Working...
                              X