SQL Abfragen mit PHP

Hallo leute,

ich bin die Neue. Ich arbeite zum ersten mal mit PostgreSQL, und schon vermisse ich mysql. Die einfachsten Abfragen haben schon Probleme bereitet, jetzt stecke ich fest. Es handelt sich um einen Webanwendung mit PHP, PostgreSQL ist in der php.ini freigeschaltet.

...
$db = new PDO(...);
...
$post_username = 'ich';
$query = 'SELECT username, password FROM user WHERE username="'.$post_username.'"';
        echo $query;
        echo '<p></p>';        
        $stmt = $db->query($query);        
        var_dump($stmt);
        echo '<p></p>';

Ausgabe:
SELECT username, password FROM user WHERE username=“ich”
bool(false)
PDO::errorInfo(): Array ( [0] => 42703 [1] => 7 [2] => ERROR: column “username” does not exist LINE 1: SELECT username, password FROM user WHERE username=“ich” ^ )

Natürlich ist der Datensatzt in der Tabelle user vorhanden, DB wird verbunden. Ich bin ratlos und finde nichts hilfreiches im Netzt. Bin dankbar für Eure Hilfe!

Die Spalte wird nicht gefunden wie da steht. Sind da ggf. Großbuchstaben beteiligt? Die Doublequotes würde ich auch zu einfachen machen.

Gruß Uwe

Danke erst mal für Deine Antwort!
Das ist das was ich nicht verstehe: die Spalte ist da! Ich habe schon jede Schreibweise versucht, " " und ’ ', irgendwas ist immer. Ob wieder wird die Spalte nicht gefunden oder sogar wird nach Spalte gesucht, die den Namen des gesuchten Inhalts trägt - in diesen Fall “ich”.

$query = "SELECT USERNAME, PASSWORD FROM USER WHERE USERNAME=".$post_username;
Ausgabe:
ERROR: column "username" does not exist LINE 1: SELECT USERNAME, PASSWORD FROM USER WHERE USERNAME=ich

das hier funktioniert scheinbar, liefert aber keinen Ergebniss:

$query = "SELECT 'USERNAME', 'PASSWORD' FROM USER WHERE 'USERNAME'='".$post_username."'";

Ausgabe:
object(PDOStatement)#3 (1) { ["queryString"]=> string(62) "SELECT 'USERNAME', 'PASSWORD' FROM USER WHERE 'USERNAME'='ich'" }
bool(false) login failed

Aber das kann doch nicht wirklich sein, dass man das so schreiben soll.

Die Tabellen und Spalten werden tatsächlich großgeschrieben
Ich muss es nicht unbedingt verstehen, was da passiert, mir reicht, wenn ich eine Lösung finde, vielleicht eine Schreibweise die bombensicher ist.

Dann brauchst Du:

select "USERNAME", "PASSWORD" from "USER" where "USERNAME"='arthur';

(Wie man allerdings doppelte Anführungszeichen innerhalb eines Strings in PHP einfügt weiß ich nicht, ich kann kein PHP)

Es ist eine ganz einfache Regel:

In SQL benötigen Bezeichner (“Identifier”, also Spalten-, oder Tabellenname) doppelte Anführungsstrichen wenn sie case-sensitive angelegt wurden (spricht mit Anführungszeichen).

Strings (Zeichenketten, Konstanten) werden in “Single quotes” gestellt.

Also ist ‘foobar’ eine Zeichenkette, “foobar” ein Spaltenname.

Wenn ein Bezeichner in doppelten Anführungszeichen steht ist er case-sensitive. “foobar” ist was anderes als “FOOBAR”.
Ohne die Anführungszeichen ist das nicht so foobar ist der gleiche Bezeichner wie FooBar oder FOOBAR.

Bei Dir wurden offensichtlich die Tabellen und Spalten alle mit Anführungszeichen angelegt z.B. create table “FOO” (“FOOBAR” integer);

Grundsätzlich ist davon abzuraten, Du hast viel weniger Probleme wenn Du einfach die doppelte Anführungszeichen immer weglässt. Dann kannst Du allerdings USER nicht als Spaltennamen verwenden, weil das ein reserviertes Wort ist. Du musst z.B. username verwenden.

Mehr zu der Syntax von SQL Bezeichner gibt’s im Handbuch: PostgreSQL: Documentation: 16: 4.1. Lexical Structure

Und bitte sag jetzt nicht, dass das bei MySQL alles anders ist: MySQL ignoriert den SQL Standard komplett und verletzt so ziemlich alle Regeln die dort aufgestellt werden.

Erstmal danke für Deine ausführliche Antwort, genau das habe ich gebrauchtö. Echt super! yupiiii

Nun, vielleicht wird Dich das überraschen, aber MySQL ist wirklich wesentlich pflegeleichter, Tabellennamen und Spaltennamen werden ohne Anführungszeichen geschrieben.

SELECT Spaltenname FROM Tabellenname

Strings aber schon

WHERE Spaltenname = ‘Spaltenwert’

Das macht das Leben leichter, wenn man den Code in PHP integrieren muss.
Also versuche ich gleich das Statement zum laufen zu bringen, drücke mir die Daumen :slight_smile:

Das ist bei Postgres genauso.

Nur wenn Du beim Anlegen der Tabelle Anführungszeichen verwendet hast, dann musst Du sie immer verwenden.

Deswegen meine Empfehlung: einfach niemals Anführungszeichen verwenden. Vor allem beim CREATE TABLE nicht.

Bist Du dann bei MySQL feststellst, dass dieses Statement auf einem Windows Server funktioniert, auf einem Linux Server nicht aber auf einem Mac dann wieder schon. Oder wenn Du die Storage Engine änderst, oder wenn Du für eine Storage Engine einen Parameter verändert hast (weil es bei MySQL von einer Kombination aus Filesystem, Betriebssystem, Storage Engine und Storage Engine Konfiguration abhängt ob ein Name Case-Sensitive ist oder nicht).

Soooo… und hier ist meine wunderschöne $query:

$query = 'SELECT "USERNAME", "PASSWORD" FROM "USER" WHERE "USERNAME"=\''.$post_username.'\' AND "PASSWORD" = \''.$post_password.'\'';

Jetzt funktioniert alles wie es sein soll :slight_smile:
Nun, wie gesagt, ich bin das erste mal mit PostgreSQL in Kontakt getreten, den Datenbank habe ich auch nicht angelegt und ich darf nichts dran verändern.

LG

Sele

Bist Du dann bei MySQL feststellst, dass dieses Statement auf einem Windows Server funktioniert, auf einem Linux Server nicht aber auf einem Mac dann wieder schon. Oder wenn Du die Storage Engine änderst, oder wenn Du für eine Storage Engine einen Parameter verändert hast (weil es bei MySQL von einer Kombination aus Filesystem, Betriebssystem, Storage Engine und Storage Engine Konfiguration abhängt ob ein Name Case-Sensitive ist oder nicht).

Na Hurra… kaum freue ich mich mit einen Problem fertig geworden zu sein, Du stellst mir weitere in Aussicht. Ich arbeite auf einer Testumgebung, der ‘Live-Server’ ist nicht mal fertig. Nun, ich werde Dein Hinweis notieren und ggf. meinen Kollegen Systemintegratoren um die Ohren hauen :wink:

Oder willst Du mir sagen, dass pgSQL da ganz anders ist? Ich hoffe schon :slight_smile:

Ja. Genau das, will ich damit sagen :slight_smile:

Ich hab nicht alles gelesen (tl;dr, you know), aber ganz echt: beachte, daß PG Groß/Kleinschreibung beachtet. Und manchmal sind es Tools wie PGAdmin, die einem da zwischenfunken. Das kann schon nerven:

test=*# create table foo ("SpAlTe" int);
CREATE TABLE
Time: 1,208 ms
test=*# insert into foo values (1);
INSERT 0 1
Time: 0,384 ms
test=*# select * from foo where SpAlTe = 1;
ERROR:  column "spalte" does not exist
LINE 1: select * from foo where SpAlTe = 1;
                                ^
Time: 0,230 ms
test=*# select * from foo where "SpAlTe" = 1;
-[ RECORD 1 ]
SpAlTe | 1

Time: 0,295 ms

Ich werde alle Abfragen jetzt erst in pgAdmin bauen und testen, bevor ich sie ins PHP integriere. Die werden nun mal immer länger und komplizierter. Die Schreibweise “Tabelle”.“Spalte” ‘Wert’ ist schon recht befremdlich für mich und mit PHP werden da noch weitere Hochkommata und Backslashes dazu kommen. Dann noch die Leerschritte, die leicht übersehen werden… Copy & paste kann schon viel Zeit und Nerven sparen :slight_smile:

Nochmal: die Hochkommata sind nur notwendig wenn diese beim Anlegen der Tabelle verwendet wurden.

Deswegen die Empfehlung: leg’ die Tabellen ohne Hochkommata an und dann hast Du Ruhe.
Vergiss einfach Hochkommata vollständig, wenn Du sie niemals verwendest hast Du auch keine Probleme.

Der folgende code läuft problemlos weil keine Hochkommata verwendet werden - und deswegen sind die Namen nicht case-sensitive:

create table FOO (id integer);
insert into Foo (ID) values (42);
select foo.iD
from foO 
where Id = 42;

Genau das ist das, der Datenbank wurde so angelegt, aber nicht von mir :slight_smile:
Ich hatte dafür den Spaß herauszufinden, wieso die Abfragen nicht funktionieren und PG solche lustige Fehlermeldungen liefert :slight_smile:
Zum Glück habe ich hier sofort Hilfe bekommen und kann weiter machen. Echt klasse, danke nochmal! :smiley: