2012-08-13 11 views
8

Estoy usando PostgreSQL 9.1.4 con hstore y el controlador PostgreSQL JDBC (9.1-901.jdbc4).Escapar hstore contiene operadores en una declaración JDBC preparada

Estoy tratando de utilizar la contiene operadores (?, ?&, ?|) en un PreparedStatement, sin embargo el carácter ? se analiza como un marcador de posición variable. ¿Se puede escapar de este personaje para enviar el operador correcto en la consulta?

Un ejemplo:

PreparedStatement stmt = conn.prepareStatement("SELECT a, b FROM table1 WHERE c ? 'foo' AND d = ?"); 
stmt.setInt(1, dValue); 
stmt.executeQuery(); 

De esta forma el siguiente ejemplo podría provocar una excepción:

org.postgresql.util.PSQLException: No value specified for parameter 2. 

Actualización:

Después de investigar el analizador de consultas en el controlador de pgjdbc this snippet parece indicar que no es posible escapar del carácter ?. Las preguntas que siguen son:

  • ¿Hay algo en la especificación JDBC que permite a un ? que se escaparon y ser otra cosa que un marcador de posición de parámetros?
  • ¿Hay alguna solución mejor para este problema que el simple uso de declaraciones simples con variables insertadas manualmente en la cadena de consulta?
+0

¿No conoce ningún JDBC pero funciona 'd = $ 1'? –

+0

No, esa no es una sintaxis válida. Lanza un error de sintaxis en '$ 1'. –

+0

Muchas interfaces de PostgreSQL prefieren marcadores de posición numerados (es decir '$ 1',' $ 2', ...), supongo que JDBC no es uno de ellos. –

Respuesta

5

Efectivamente, parece que el analizador SQL de Java no es compatible con hstore.

Pero como la sintaxis c ? 'foo' es equivalente a exist(c, 'foo'), puede solucionar este problema fácilmente. Eche un vistazo a la siguiente página para ver cuáles son los operadores detallados para hstore.

Postgres hstore documentation

+0

Gracias, no vi el operador detallado abajo. –

+7

Es importante tener en cuenta que 'existe (c, 'foo')' no * usa * un índice. Verifique un plan de consulta con y sin para ver la diferencia. – magneticMonster

+2

También este método no funciona para columnas JSONB. – expert

-1

Si desea añadir varios pares de valores clave que utilizan PreparedStatement, puede hacerlo:

PreparedStatement ps = c.prepareStatement(
        "insert into xyz(id, data) values(?, hstore(?, ?))"); 

ps.setLong(1, 23456L); 
ps.setArray(2, c.createArrayOf("text", new String[]{"name", "city"})); 
ps.setArray(3, c.createArrayOf("text", new String[]{"Duke", "Valley"})); 

Esto insertará: 23456, 'name=>Duke, city=>Valley'

+0

esto no tiene nada que ver con la pregunta –

Cuestiones relacionadas