Hi
Ich versuche ein prepared Statement mit einer Liste abzusetzen, das Statement im PGAdmin schaut so aus und liefert mir 2 Zeilen:
select * from kunden where kundennummer::bigint in (111,222)
Als Prepared Statement gelingt mir das aber nicht, hier der logeintrag vom SQL:
2019-04-30 10:36:50 CEST FEHLER: ungültige Eingabesyntax für ganze Zahl: »111,222«
2019-04-30 10:36:50 CEST ANWEISUNG: select * from kunden where kundennummer::bigint in ($1)
Wie muß ich die Werte in der liste trennen ???
habs mit Pinkt, komma,Strichpunkt und abstand probiert, immer der gleiche Fehlerlog
lg S.
Die Spalte Kundennummer enthält Werte die sich nicht in einen Integer wandeln lassen.
Es sieht so aus, als würden mehrere Zahlen durch Komma getrennt drin stehen. Das ist eine richtig, richtig schlechte Idee und verletzt die grundlegenden Prinzipien eines sauberen Datenmodells.
Glücklicherweise kann das mit Postgres trotzdem lösen, indem man die Liste von Zahlen in ein Array umwandelt und dann prüft ob die Werte in dem Array vorkommen:
select *
from kunden
where string_to_array(kundennummer, ',')::int[] && array[111,222];
Das liefert alle Datensätze in denen mindestens eine der beiden Zahlen 111 oder 222 vorkommt.
Wenn Du die Datensätze möchtest in denen beide Zahlen vorkommen, musst Du den “contains” Operator nehmen:
select *
from kunden
where string_to_array(kundennummer, ',')::int[] @> array[111,222];
Aber die korrekte Lösung ist das Datenmodell so schnell wie möglich zu korrigieren.
Ich hab eine Tabelle, die Kundennummer ist ein KEY-Wert (ist ein Bigint not null) und ich will die Datensätze der Kunden mit der Kundennummer.
Das ganze als prepared Statement.
das cast auf ::bigint macht im Statement keinen sinn, da es schon ein bigint ist, sorry verwirrt etwas.
Dann versuchst Du wohl einen String, mit durch Komma getrennten Zahlen als Parameter für ein IN Statement zu übergeben. Das funktioniert so nicht.
Was für eine Programmiersprache verwendest Du? Wenn Du da nur einen String übergeben kannst, dann könntest Du sowas machen:
select *
from kunden
where kundennummer = any(string_to_arryay($1, ',')::int[]);
Damit ist der Parameter ein String der dann in ein Array umgewandelt wird.
(Ein “x in (1,2,3)” wird vom Optimizer auch in ein “x = any(array[1,2,3])” umgeschrieben)
test=*# create table kunden (kundennummer bigint, name text);
CREATE TABLE
test=*# insert into kunden values (1, 'Kunde 1');
INSERT 0 1
test=*# insert into kunden values (2, 'Kunde 2');
INSERT 0 1
test=*# insert into kunden values (111, 'Kunde 111');
INSERT 0 1
test=*# insert into kunden values (222, 'Kunde 222');
INSERT 0 1
test=*# insert into kunden values (333, 'Kunde 333');
INSERT 0 1
test=*# commit;
COMMIT
test=# select * from kunden where kundennummer in (111,222);
kundennummer | name
--------------+-----------
111 | Kunde 111
222 | Kunde 222
(2 rows)
test=*# prepare abfrage (bigint[]) as select * from kunden where kundennummer = any ($1);
PREPARE
test=*# execute abfrage(array[111,222]);
kundennummer | name
--------------+-----------
111 | Kunde 111
222 | Kunde 222
(2 rows)
@castorp: Funktioniert (auch wenn ich das Statement nicht verstehe, da mach ich mich noch schlau)
Abfrage wird von PHP erzeugt
$kundennr = "111,333";
$query = "select * from kunden where kundennummer = any(string_to_array(:kdnr, ',')::bigint[])"; // funktioniert !!
$result = $pdo_pg_conn->prepare($query);
$result->execute(array(':kdnr' => $kundennr));
echo "Zeilen:".$result -> rowcount()."/z";
$datensatz = $result->fetchall(PDO::FETCH_ASSOC);
mit print_r($datensatz); bekomme ich nun alles gelistet.
@akretschmer: bei deinem hab ich wieder 0 Ergebnisse bekommen, hab ich auf die schnelle nicht hinbekommen.
BESTEN DANK !