2015-05-26 9 views
12

... oder die Fragezeichen Frage.jsonb existentielle Operatoren mit parametrisierten Abfragen

Ich implementiere derzeit die Suchfunktionalität für eine Postgres-Datenbank in PHP, die den neuen JSONB-Typ verwendet.

Um dies zu erreichen, führe ich vorbereitete Anweisungen mit benannten Platzhaltern aus.

Allerdings habe ich ein interessantes Problem beim Versuch, einige der neuen Postgres JSON containment and existence operators zusammen mit benannten Platzhaltern zu verwenden.

Die Basis des Problems ist, dass die Operatoren selbst das Fragezeichen ? als Teil ihrer Syntax verwenden. d. h.

? Liegt die Schlüssel/Element-Zeichenfolge innerhalb des JSON-Werts?

?| Gibt es eine dieser Schlüssel-/Elementzeichenfolgen?

?& Sind alle diese Schlüssel/Element-Strings vorhanden?

Das bedeutet, ich habe Anweisungen, die in PHP so aussehen.

Dies schlägt fehl, weil das Fragezeichen als Platzhalter interpretiert wird Um dies zu umgehen, habe ich versucht, den Operator selbst zu einem benannten Parameter zu machen.

$sth = $dbh->prepare("SELECT * FROM stuff WHERE meta :operator :value"); 
$sth->bindValue(1, $operator, PDO::PARAM_STR); 
$sth->bindValue(2, $value, PDO::PARAM_STR); 
$sth->execute(); 

dies jedoch wirft nur den gleichen Fehler wie die nackte Operator, das heißt

ERROR: syntax error at or near \"$1\"1

Hat jemand über dieses Problem kommen oder kann jemand denken Sie an eine gute Abhilfe?

Gibt es eine Möglichkeit zu entkommen oder das Fragezeichen zu übergeben, so dass man die postgres jsonb containment und existence operators mit PDO parametrisierten Abfragen verwenden kann?

Antwort

18

Sie können entsprechende Funktionen anstelle von Operatoren verwenden (jsonb_exists, jsonb_exists_any, jsonb_exists_all). Zum Beispiel führen Sie \do+ "?" in psql, um Funktionsname von zu sehen? Operator.

oder definieren Sie Ihren eigenen Operator ohne "?" Symbol stattdessen.

Zum Beispiel:

CREATE OPERATOR [email protected] (LEFTARG = jsonb, RIGHTARG = text, PROCEDURE = jsonb_exists)  
CREATE OPERATOR [email protected]| (LEFTARG = jsonb, RIGHTARG = text[], PROCEDURE = jsonb_exists_any) 
CREATE OPERATOR [email protected]& (LEFTARG = jsonb, RIGHTARG = text[], PROCEDURE = jsonb_exists_all) 

so dass man verwenden [email protected], [email protected]| und [email protected]& anstelle von ?, ?| und ?& sind. z.B.

$sth = $dbh->prepare("SELECT * FROM stuff WHERE meta [email protected] :value"); 
$sth->bindValue(1, $value, PDO::PARAM_STR); 
$sth->execute(); 
+0

Ha! Daran hatte ich wirklich noch nicht gedacht, werde es jetzt ausprobieren, vielen Dank! – Fraser

+0

Brilliant, Operator-Definition ist eine ideale Lösung, da es bedeutet, dass ich die gleiche Struktur verwenden kann, ohne mit Funktionsaufrufen umzugehen. Ich schätze es wirklich, hatte mir einige Stunden am Kopf kratzt und dachte dabei eher an das PDO-Ende als an das db-Ende. Nochmals vielen Dank. – Fraser

+0

Hinweis.In der Dokumentation gibt es keine Funktionen wie jsonb_exists, jsonb_exists_any, jsonb_exists_all, aber sie funktionieren tatsächlich wie jsonb_exists (jsonb, text) – Swayok

Verwandte Themen