hawkmaster: Problem mit franz. Apostroph beim Importieren in DB

Hallo zusammen,

In einem SQL Script stehnt z.b.

  
INSERT INTO mytext (textid,english,french,german) VALUES ('323914','Upper Tray','Bac supérieur d\'unité','Oberer Schacht');  

Dies kann ich in MySQL problemlos importieren.
Wenn ich dieses Script jedoch in Postgres importieren möchte, bricht der Import mit einer Fehlermeldung ab.
"WARNUNG:  nicht standardkonforme Verwendung von ' in Zeichenkettenkonstante"
"HINT:  Verwenden Sie '', um Quotes in Zeichenketten zu schreiben, oder verwenden Sie die Syntax für Escape-Zeichenketten (E'...')."

Laut Doku soll man doch einfache Anführungszeichen für Daten und doppelte für Bezeichner verwenden. Und das Hochkomm innerhalb eines Strings muss doch auch mit dem \ maskiert werden oder?

Wie kann man die Daten richtig importieren?
vielen Dank und viele Grüße
hawk

  1. Hi,

    "HINT:  Verwenden Sie '', um Quotes in Zeichenketten zu schreiben, oder verwenden Sie die Syntax für Escape-Zeichenketten (E'...')."

    Und diesen Hinweis einfach zu befolgen, und den Wert einfach als
    'Bac supérieur ''unité'
    zu notieren, bekommst du nicht gebacken?

    Laut Doku soll man doch einfache Anführungszeichen für Daten und doppelte für Bezeichner verwenden. Und das Hochkomm innerhalb eines Strings muss doch auch mit dem \ maskiert werden oder?

    http://www.postgresql.org/docs/8.2/static/runtime-config-compatible.html#GUC-BACKSLASH-QUOTE

    Wie kann man die Daten richtig importieren?

    Ich finde es erstaunlich, wie wenig eigene Bemühung bzw. Fähigkeit du hier regelmäßig darin zeigst, dir solche Informationen selber zu erarbeiten.

    MfG ChrisB

    --
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
    1. Hallo Chris,

      danke für den Rüffel und Hinweis.

      Auch wenn du es nicht glaubst. Aber ich habe schon in der PG Doku nachgelesen
      und zwar hier
      http://www.postgresql.org/docs/8.3/interactive/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS

      Ich habe auch gelesen das man wohl solche Strings mit einem E maskieren kann, also
      E'foo
      Das mit den doppelten '' war mir neu und habe ich auch gelesen.
      Ich bin und war mir nur nicht sicher, ob dies dann Standard SQL ist und man dies z.b. auch für MySQL und MSSQL verwenden kann.

      Du hast aber insofern recht. Ich hätte vor dem posten bzw. im Post auf dies hinweisen können.

      vielen Dank und viele Grüße
      hawk

      1. Hallo,

        Das mit den doppelten '' war mir neu und habe ich auch gelesen.
        Ich bin und war mir nur nicht sicher, ob dies dann Standard SQL ist und man dies z.b. auch für MySQL

        nein.

        und MSSQL verwenden kann.

        Ja. Einfache Anführungszeichen maskiert man in T-SQL durch Verdopplung.

        Ich dachte, das sei einer der Gründe, warum Du PDO mit prepared Statements nutzt (ist nämlich ein netter Nebeneffekt, den man gerne mitnimmt).

        Freundliche Grüße

        Vinzenz

        1. Hi!

          Das mit den doppelten '' war mir neu und habe ich auch gelesen.
          Ich bin und war mir nur nicht sicher, ob dies dann Standard SQL ist und man dies z.b. auch für MySQL
          nein.

          Doch.

          Lo!

          1. Hallo dedlfix,

            Das mit den doppelten '' war mir neu und habe ich auch gelesen.
            Ich bin und war mir nur nicht sicher, ob dies dann Standard SQL ist und man dies z.b. auch für MySQL
            nein.
            Doch.

            ich sollte mal wieder öfters die Doku lesen.
            Danke für den Hinweis.

            Freundliche Grüße

            Vinzenz

        2. Hi Vinzenz,
          vielen Dank für deine Hilfe.

          Ich dachte, das sei einer der Gründe, warum Du PDO mit prepared Statements nutzt (ist nämlich ein netter Nebeneffekt, den man gerne mitnimmt).

          Ähm, ich verstehe nicht genau was du meinst. Ich hatte PDO gewählt um möglichst flexibel zu sein, was die DB betrifft. (Auch wenn es später vielleicht nur bei Postgres bleibt)
          Prepared Statements waren und sind auch ein Grund wegen Sicherheit und SQL Injection.

          In diesem Zusammenhand aber mit dem Hochkomma ist mir nicht klar wie du das meinst. Es ist ja so, dass ich mit PHP ein Import SQL Script erstelle, das man dann später z.b. PGAdmin III importieren kann.
          Oder meinst du das Problem wäre nicht aufgetreten, wenn ich anstatt den Import mit PGAdmin III zu machen, dies über ein eigenes Import Script mittels PDO gemacht hätte?

          vielen Dank und viele Grüße
          hawk

          1. Hi,

            Ich dachte, das sei einer der Gründe, warum Du PDO mit prepared Statements nutzt (ist nämlich ein netter Nebeneffekt, den man gerne mitnimmt).

            Ähm, ich verstehe nicht genau was du meinst. Ich hatte PDO gewählt um möglichst flexibel zu sein, was die DB betrifft. (Auch wenn es später vielleicht nur bei Postgres bleibt)
            Prepared Statements waren und sind auch ein Grund wegen Sicherheit und SQL Injection.

            In diesem Zusammenhand aber mit dem Hochkomma ist mir nicht klar wie du das meinst.

            Ganz einfach - wenn du prepared statements nutzt, musst du dich gar nicht um die Behandlung der Daten kümmern, Maskierungen für Sonderzeichen sind dabei nicht erforderlich.

            In einer „normalen“ Query müssen die Sonderzeichen aus genau dem Grund behandelt werden, damit der Query-Parser das Statement nach den vorliegenden Syntax-Regeln analysieren kann - weil hier „Befehl“ und Daten in einem Textstring „gemischt“ auftreten.

            Bei prepared statements werden aber das Statement und die Daten separat an die Datenbank übergeben - d.h., eine „Verwechslung“ von Befehls-Bestandteilen und Daten kann hier gar nicht passieren, vollkommen egal, was für Zeichen die Daten enthalten.

            Es ist ja so, dass ich mit PHP ein Import SQL Script erstelle, das man dann später z.b. PGAdmin III importieren kann.

            In so einem Fall musst du natürlich die Daten entsprechend behandeln, in reinem SQL in Textform kannst du keine prepared statements nutzen.

            Oder meinst du das Problem wäre nicht aufgetreten, wenn ich anstatt den Import mit PGAdmin III zu machen, dies über ein eigenes Import Script mittels PDO gemacht hätte?

            Wenn du dabei prepared statements genutzt hättest, dann nein.

            Aber für größere Datenmengen kann natürlich eine Textdatei, die reine SQL-Statements enthält und von der Datenbank bzw. über ein Frontend direkt importiert werden kann, von der Performance her günstiger sein als ein Script, welches selber mit der Datenbank kommuniziert.

            MfG ChrisB

            --

            RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
            1. Hallo ChrisB,

              nochmals vielen Dank für deine Hinweise.

              Aber für größere Datenmengen kann natürlich eine Textdatei, die reine SQL-Statements enthält und von der Datenbank bzw. über ein Frontend direkt importiert werden kann, von der Performance her günstiger sein als ein Script, welches selber mit der Datenbank kommuniziert.

              Ja, ich importiere hier größere Datenmengen.
              Nochmals zum escapen.
              Ich habe mal mit dem PGAdmin versuche gemacht.
              Soweit ich es richtig verstanden habe. Waren die Meldungen
              "WARNUNG:  nicht standardkonforme Verwendung von ' in Zeichenkettenkonstante"
              Ja keine Fehler sondern nur "Warnungen". Die Inserts wurden trotzdemgemacht.

              Ich hatte vorher für mein Import Script "addslashes()" verwendet um die Zeichen '," und \ zu maskieren, falls diese in einem String vorkommen.D.h. es wurde überall ein Backslash vor diese Zeichen gesetzt.

              Wenn ich im PgAdmin folgendes eingebe
              insert into test (mytext) values ('Bac supérieur d''unité');
              dann ist dies ok, ohne Fehlermeldng. Ich habe hier also mit einem zusätzlichen ' maskiert.
              Angenommen in dem String ist aber noch ein " oder \ drin:
              insert into test (mytext) values ('Bac supérieur d''uni"té');
              Dann kommt wieder die Meldung:
              HINT:  Verwenden Sie die Syntax für Escape-Zeichenketten, z.B. E'\r\n'.
              Ich dachte man könnte auch für diese Zeichen zwei einfache Hochkommas verwenden. Also:
              insert into test (mytext) values ('Bac supérieur d''uni''"té');
              Aber dann steht in der Spalte "d'uni'"te" drin.

              Die Frage ist also. Wenn es "nur" Warnmeldungen sind. Könnte man dann nicht doch den Backslash als Escape zeichen lassen?

              By the way: Hast du eine email oder kannst du mich mal anmailen?

              vielen Dank und viele Grüße
              hawk

              1. Mahlzeit hawkmaster,

                Ich hatte vorher für mein Import Script "addslashes()" verwendet um die Zeichen '," und \ zu maskieren, falls diese in einem String vorkommen.D.h. es wurde überall ein Backslash vor diese Zeichen gesetzt.

                Warum das? Es gibt auch für PostgreSQL eine entsprechende PHP-Funktion: pg_escape_string()

                insert into test (mytext) values ('Bac supérieur d''uni"té');

                Also ein einfaches Anführungszeichen (das korrekt maskiert wurde) und ein doppeltes Anführungszeichen (das nicht korrekt maskiert wurde) ...?

                insert into test (mytext) values ('Bac supérieur d''uni''"té');

                Das hat aber mit dem o.g. irgendwie nicht mehr viel zu tun.

                Aber dann steht in der Spalte "d'uni'"te" drin.

                Was auch vollkommen korrekt ist. Was hättest Du denn sonst erwartet?

                MfG,
                EKKi

                --
                sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
                1. Hallo EKKI,
                  vielen Dank auch an dich für deine Hilfe.

                  Warum das? Es gibt auch für PostgreSQL eine entsprechende PHP-Funktion: pg_escape_string()

                  Das ist mir bewusst. Aber erstens arbeite ich ja mit PDO und zweitens erstelle ich ja ein SQL Script bzw. eine SQL Daei die später nach Möglichkeit von verschiedenen DBs eingelesen werden sollte.

                  z.b.

                    
                  ..  
                  $sql_output .= "INSERT INTO mytext  (textid,vendorid,txttype,name,installdate) VALUES ($TextID,$vendorid,$txttype,$Name,$InstallDate);\n";  
                  ..  
                  $SqlOutputFile = "Install_.sql";  
                  $file = fopen($SqlOutputFile,"w");  
                  fwrite($file, $sql_output);  
                  fclose($file);  
                  
                  

                  vielen Dank und viele Grüße
                  hawk

              2. Hi,

                Ich hatte vorher für mein Import Script "addslashes()" verwendet um die Zeichen '," und \ zu maskieren, falls diese in einem String vorkommen.D.h. es wurde überall ein Backslash vor diese Zeichen gesetzt.

                addslashes ist immer nur ein Notbehelf - wenn möglich, sollte man die Escaping-Funktion verwenden, die die Datenbank-Schnittstelle bereitstellt.

                Für PostGreSQL gibt es in PHP bspw. explizit die Funktion pg_escape_string, um Daten für das Einfügen in ein Textfeld korrekt zu behandeln.
                Hast du die mal ausprobiert?

                Die Frage ist also. Wenn es "nur" Warnmeldungen sind. Könnte man dann nicht doch den Backslash als Escape zeichen lassen?

                Könnte man, allerdings ist man damit von der Serverkonfiguration abhängig, sofern man den Backslash innerhalb „normaler“ Textliterale benutzt; mit der Benutzung der “escape string constant”-Schreibweise E'foo' wäre man da auf der sicheren Seite.

                By the way: Hast du eine email oder kannst du mich mal anmailen?

                Worum geht's?

                MfG ChrisB

                --
                RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                1. Hallo ChrisB,

                  Worum geht's?

                  ich habe bei meiner Migration von MySQL zu Postgres einiges an Problemen gehabt und dies mal so für mich dokumentiert. Ich überlege nun, ob man dies event. hier in Self in einem WIKI zur Verfügung stellen könnte.
                  Allerdings ist dies sicher nicht komplett und benötigt Ergänzungen. Daher dachte ich, ob mir ein paar Experten hier dabei helfen könnten, bzw. später dann mal korrektur lesen?

                  vielen Dank und viele Grüße
                  hawk

                  1. Hi,

                    ich habe bei meiner Migration von MySQL zu Postgres einiges an Problemen gehabt und dies mal so für mich dokumentiert. Ich überlege nun, ob man dies event. hier in Self in einem WIKI zur Verfügung stellen könnte.

                    Da kannst du gleich loslegen, wenn du willst - http://wiki.selfhtml.org/wiki/SELFHTML:Über :-)

                    (Es war glaube ich „Konvention“, umfangreichere Artikel erst mal auf der eigenen Benutzerseite zu erstellen, damit sie dort dann diskutiert werden können, bevor sie „live“ gehen. Aber dazu kannst du auch noch mal einen neuen Thread aufmachen und fragen, oder dich mal an dedlfix wenden.)

                    Allerdings ist dies sicher nicht komplett und benötigt Ergänzungen. Daher dachte ich, ob mir ein paar Experten hier dabei helfen könnten, bzw. später dann mal korrektur lesen?

                    Korrekturleser findest du bestimmt, wenn erst mal ein Entwurf steht.
                    (Wobei ich mich von den „Experten“ gleich mal ausklammern möchte, was PostgreSQL angeht.)

                    MfG ChrisB

                    --
                    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
  2. @@hawkmaster:

    nuqneH

    BTW, solche Probleme treten gar nicht erst auf, wenn man die typografisch richtigen Apostrophe (Anführungszeichen, …) verwendet: d’unité.

    ' und " bleiben den Markup-, Stylesheet-, Script- und Datenbanksprachen vorbehalten; im Text braucht man diese Zeichen nicht.

    Qapla'

    --
    Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
    (Mark Twain)
    1. Hallo Gunnar,
      vielen Dank auch für deinen Hinweis.

      BTW, solche Probleme treten gar nicht erst auf, wenn man die typografisch richtigen Apostrophe (Anführungszeichen, …) verwendet: d’unité.

      Das Problem ist. Ich hole die Texte und Strings aus vorhandenen Dateien. In der original Datei steht z.b. dieses Wort so drin:
      Bac sup<e9>rieur d'unit<e9>

      Du siehst, auch hier wird mit dem einfachen Hochkomma gearbeitet. Die Zeichen zwischen <> filtere ich dann und wandle sie um.

      vielen Dank und viele Grüße
      hawk