Maison >base de données >tutoriel mysql >Comment utiliser les opérateurs PostgreSQL JSONB avec des points d'interrogation '?' dans JDBC ?

Comment utiliser les opérateurs PostgreSQL JSONB avec des points d'interrogation '?' dans JDBC ?

Barbara Streisand
Barbara Streisandoriginal
2024-12-30 02:47:28198parcourir

How to Use PostgreSQL JSONB Operators with Question Marks

Comment utiliser l'opérateur PostgreSQL JSON(B) contenant un point d'interrogation "?" dans JDBC

PostgreSQL propose plusieurs méthodes qui utilisent des points d'interrogation comme noms Une partie des opérateurs ASCII intelligents, tels que ces JSON Opérateurs :

  •  ? : Une chaîne existe-t-elle en tant que clé de niveau supérieur dans une valeur JSON ?
  • ?| : L'une de ces chaînes de tableau existe-t-elle en tant que clés de niveau supérieur ?
  • ?& : ces chaînes de tableau existent-elles en tant que clés de niveau supérieur ?

Le problème est que le pilote JDBC officiel de PostgreSQL ne semble pas être capable d'analyser correctement les chaînes SQL contenant de tels opérateurs. Il considère le point d'interrogation comme une variable de liaison JDBC ordinaire. Le code suivant...

try (
    PreparedStatement s = c.prepareStatement("select '{}'::jsonb ?| array['a', 'b']");
    ResultSet rs = s.executeQuery()) {
    ...
}

... lève une exception :

org.postgresql.util.PSQLException: Für den Parameter 1 wurde kein Wert angegeben.
    at org.postgresql.core.v3.SimpleParameterList.checkAllParametersSet(SimpleParameterList.java:225)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:190)
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:424)
    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:161)
    at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:114)

Comment utiliser cet opérateur ?

Il existe deux solutions possibles :

1. Utilisez des instructions statiques au lieu d'instructions préparées

C'est la solution de contournement la plus simple, mais vous perdra tous les avantages des instructions préparées (performances, protection contre les injections SQL, etc.). Cependant, cela fonctionnera :

try (
    Statement s = c.createStatement();
    ResultSet rs = s.executeQuery("select '{}'::jsonb ?| array['a', 'b']")) {
    ...
}

2. Évitez d'utiliser des opérateurs. Utilisez plutôt une fonction (remarque : l'indexation ne peut pas être utilisée). L'opérateur

n'est qu'un sucre syntaxique pour la fonction prise en charge, qui existe dans pg_catalog. Voici comment trouver les noms de ces fonctions :

SELECT 
  oprname, 
  oprcode || '(' || format_type(oprleft,  NULL::integer) || ', ' 
                 || format_type(oprright, NULL::integer) || ')' AS function
FROM pg_operator 
WHERE oprname = '?|';

L'opération ci-dessus produit :

oprname  function
----------------------------------------------------------------------------------
?|       point_vert(point, point)
?|       lseg_vertical(-, lseg)
?|       line_vertical(-, line)
?|       jsonb_exists_any(jsonb, text[])    <--- this is the one we're looking for
?|       exists_any(hstore, text[])

La solution la plus simple n'est donc pas d'utiliser l'opérateur, mais la Fonction correspondante :

try (
    PreparedStatement s = c.prepareStatement("select jsonb_exists_any('{}'::jsonb, array['a', 'b']");
    ResultSet rs = s.executeQuery()) {
    ...
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn