ich benutze für das automatische Einspielen von Daten in eine Postgres-DB prepared statements. Sonderzeichen maskieren ich mit \, dies führt jedoch zu der bekannten Fehlermeldung: Please use E’’ syntax… blabla .
Es funktioniert zwar alles, aber ich würde die Meldungen trotzdem gerne loswerden. Dabei bin ich auf ein Problem gestoßen:
Ein prepared statement sieht wie folgt aus:
INSERT INTO foo_table (foo, bar, baz, foobar, barfoo) VALUES($1::int,(SELECT timestamptz 'epoch' + $2::int * interval '1 second'),$3::int,$4::text,$5::text)
Wie schon zu sehen, kommt die Meldung, wenn in einer der letzten beiden Spalten ein \ auftaucht.
Ich habe probiert, das statement folgendermaßen abzuändern:
INSERT INTO foo_table (foo, bar, baz, foobar, barfoo) VALUES($1::int,(SELECT timestamptz 'epoch' + $2::int * interval '1 second'),$3::int,E'$4::text',E'$5::text')
Das funktioniert jedoch nicht. Hat jemand eine Idee?
Lass mal das Casten der Datentypen ganz weg. Du brauchst das nicht, weil die Datenbank schon weiß, dass dort ein ::text ankommt. Außerdem müssten die ::text außerhalb der ‘’ stehen.
Hmm, jetzt war ich verwirrt und hatte ursprünglich angenommen, das $1 steht für das Ergebnis eines Regexp.
Du nutzt Prepared Statements? Da drin brauchst du keine Escapes. Damit musst du (und darfst du) deine Daten nicht escapen. Du schickst die beim Ausführen des Prepared Statements einfach so an die Datenbank, wie sie ankommen.
Wenn du Prepared Statements verwendest, brauchst du kein Escaping.
Das Escaping ist notwendig, wenn du die Anfrage als String zusammensetzt und direkt ausführst. Also so etwas:
select ... from tabelle where id = '1'
Dann müsstest du die 1 escapen. Wenn statt der 1 dir jemand ein ’ als Wert übermittelt, sieht die Anfrage nämlich sonst so aus:
select ... from tabelle where id = '''
Wenn du Prepared Statements verwendest, wird die Anfrage in der Datenbank geparst und vorbereitet und erst später beim Ausführen kommen die Daten hinzu. Beim Ausführen findet aber kein Parsen mehr statt, demzufolge kann niemand aus der SQL-Anfrage ausbrechen und demzufolge muss man die Daten bei einem Prepared Statement nicht escapen.
Hinweis in eigener Sache: das ist Thema in meiner Schulung, siehe Signatur.
Speziell zu deiner letzten Frage: woher weisst du, ob es nichts zu escapen gibt? Kontrollierst du die Inhalte, sprich, kommen die aus einer vertrauenswürdigen Quelle?
Eine vertrauenswürdige Quelle wäre zum Beispiel der Integer, den du vorher aus einer Tabelle ausgelesen hast und von dem du demzufolge weißt, das sich da drin kein Text sondern nur eine Zahl befinden kann.