UPDATE tab set col = 'Test\r\nTest' ... funktioniert nicht mehr

Hi,

sämtliche SQL-Calls die Backslashes enthalten, wie z.B. bei Zeilenumbrüchen

“UPDATE tab set col = ‘Test\r\nTest’”

oder beliebigen Usereingaben

“UPDATE tab set col = ‘Test\Test’”

funktionierten bis mindestens PGSQL 8.0.

Seit spätestens PGSQL 8.2 braucht man dafür angeblich eine neu Syntax, mit “E” davor oder so.

Kann man das irgendwie konfigurieren, oder gibts dafür einen bequemen workaround?

Wir setzen PGSQL in einem PHP Projekt ein. Weder über PHP noch über die Konsole funktionieren die Calls.

Kann mir/uns wer helfen?

Vielen Dank

selber gelöst … vielleicht hilfts jemandem:

siehe 1. Punkt unter “E.5.2. Migration to version 8.2” auf http://developer.postgresql.org/pgdocs/postgres/release-8-2.html

"Set escape_string_warning to on by default (Bruce)

This issues a warning if backslash escapes are used in non-escape (non-E’’) strings."

In 8.2. liefert jeder Call der einen “” beinhaltet eine Warning, wenn “standard_conforming_strings” off ist.

Da wir den “” nicht zum escapen nutzen (wäre ja nicht standard-konform) muss man lediglich “SET standard_conforming_strings = ON” ausführen, danach funktioniert wieder alles.

Vielen Dank an jeden der sich Gedanken gemacht hat.

CLOSED

Noch nicht ganz closed:

Ihr solltet einfach die PHP Funktionen zum Quoten von Daten verwenden, dann seit ihr auch in Zukunft sicher vor Änderungen.

Häh?

Versteh ich nicht ganz. Welche Funktionen meinst du, pg_escape_string/pg_escape_bytea.

Hätte man da nicht das gleiche Problem, oder fragen die bei der DB nach, welche settings gesetzt sind?

Problem ist, wir arbeiten mit mehreren ANSI-DB-Systemen, d.h. das escapen haben wir selber gemacht …

Ähm, Leute, auf alle Fälle solltet ihr die Quotingfunktionen der DB nutzen, die sollten wissen, was man alles wie quoten muss.

Wenn ihr mit mehreren DBs arbeitet: es gibt nette Software wie AdoDB, die in so einem Fall einspringen kann.

Ihr wollt das Rad wirklich 3- oder 4 Mal erfinden, stimmts?

Hehe, ja, das war halt so das wir vor AdoDB waren, nur unseres is nicht OpenSource - als 3 Mann-Betrieb muss man von was leben …

Aber nochmal, was meinst du mit “Quotingfunktionen der DB nutzen”, versteh’s immer noch nicht …

Danke nochmal

Na das, was dir die Programmiersprache bietet. Also pg_escape_string dann im Falle von PHP/PostgreSQL.
Entsprechende Funktionen gibt es in jeder Programmiersprache für jede unterstützte Datenbank.

Wenn es an dieser Stelle Probleme geben sollte, ist der richtige Weg nicht etwa eine eigene Quotingfunktion (Rad neu erfinden, eigene Fehler einbauen) sondern ein Bugreport für die Programmiersprache.

Hi,

okay, ja - leider gibt’s weder für MSSQL noch für ORACLE ein äquivalent für pg_escape_string … außer str_replace(“HOCKOMMA”, “HOCKOMMA_HOCKOMMA”, $sql).

Ich bin mir auch nicht sicher ob pg_escape_string() mehr macht, und ob der Einsatz dessen uns vor obigem “Problem” bewahrt hätte. Du hast da sicher mehr Einblick … woooo, 666. Post … ein böses Omen? :slight_smile:

Danke für die Diskussion … freu mich über mehr … und das wir unser eigenes DB-Abstraktions-Süppchen kochen mag zu hinterfragen sein, aber das is unsere Sorge.

Nein, Oracle zum Beispiel macht es gleich “richtig” und erzeugt prepared Queries, die Daten werden dann an diesen Query übergeben. Dadurch muss im eigentlichen Query gar kein Escaping mehr stattfinden und die Daten werden im “Body” des Queries mitgeschickt und können keinen Schaden anrichten.

In PostgreSQL kann man genau diesen Weg auch gehen, wenn man ein einheitliches Vorgehen haben möchte.

Hi,

ja, das ist der Weg den wir gegangen sind, ein Wrapper der prepared queries für jedes DBMS simuliert.

Also wir haben das Rad nicht neu erfunden, unseres hat nur auch ABS und Seitenaufprallschutz.

Dann kannst du mir aber sicherlich erklären, wieso ihr dann Daten escapen müsst? Das wäre bei prepared Queries nicht notwendig …

Ich sagte es wird simuliert. Wenn ich jetzt weiter erzähle krieg ich nur wieder Anschiss - es funktioniert - Problem is längst gelöst, ich will jetzt mittagessen.

Mahlzeit & Danke

Hi,

nochmal ich.

Also, escapen muss ja trotzdem, nehm ich an … also ich mach es im Moment, nur dass ich halt nicht die query escape, sondern die Parameter.

Ich weiss jetzt nicht wie das ORACLE macht, aber früher oder später muss die Query “escaped” vorliegen.

Bei mir läuft das im Moment so ähnlich wie hier (Bsp. aus`m Netz geklaut).

$dbh->prepare(‘SELECT * FROM users WHERE name=:name AND
email=:email’);
$dbh->execute(array(’:name’=>‘Alejandro’,’:email’=>‘alejandro@domain.com’));

Innerhalb von execute werden die Parameter dann an die query übermittelt, und je nach dem ob’s ein Textfeld ist, muss halt es escaped werden.

Oder geht das schlauer?