2012-09-08 12 views
5

Deseo crear una "declaración preparada" en postgres usando el módulo node-postgres. Quiero crearlo sin vincularlo a los parámetros porque el enlace tendrá lugar en un bucle.node-postgres: cómo preparar una declaración sin ejecutar la consulta?

En el documentation leí:

query(object config, optional function callback) : Query 
If _text_ and _name_ are provided within the config, the query will result in the creation of a prepared statement. 

Probé

client.query({"name":"mystatement", "text":"select id from mytable where id=$1"}); 

pero cuando intento pasar sólo las teclas de nombre de texto & en el objeto de configuración, consigo una excepción:

(traducido) el mensaje es vinculante 0 parámetros, pero la instrucción preparada espera 1

¿Hay algo que me falta? ¿Cómo se crea/prepara una declaración sin vincularla a un valor específico para evitar volver a prepararla en cada paso de un ciclo?

Respuesta

9

Acabo de encontrar un answer on this issue por el autor de node-postgres.

Con node-postgres la primera vez que emite una consulta con nombre es analizada, encuadernada y ejecutada a la vez. Cada consulta posterior emitida en la misma conexión con el mismo nombre omitirá automáticamente el paso "analizar" y solo volverá a enlazar y ejecutar la consulta ya planificada.

Actualmente node-postgres no admite una forma de crear una consulta con nombre, preparada y no ejecutar la consulta. Esta característica es compatible con dentro de libpq y el protocolo cliente/servidor (utilizado por los enlaces de JavaScript puro ), pero no lo expuse directamente en la API. I pensé que agregaría complejidad a la API sin ningún beneficio real. Dado que las declaraciones con nombre están vinculadas al cliente en el que están creadas, si el cliente se desconecta y se vuelve a conectar o se devuelve un cliente diferente desde el grupo de clientes, la sentencia con nombre no tendrá más tiempo (requiere un nuevo análisis)

2

Actualización: Leyendo de nuevo su pregunta, esto es lo que creo que debe hacer. También debe pasar una matriz de "valor".

Solo para aclarar; donde normalmente "prepara" su consulta, solo prepare el objeto que le pase, sin la matriz de valores. Luego, en donde normalmente "ejecuta" su consulta, establezca la matriz de valores en el objeto y páselo a la consulta. Si es la primera vez, el controlador hará la preparación real para usted la primera vez, y hará el enlace y la ejecución sencillos durante el resto de la iteración.

+0

El problema con esta solución es que la declaración preparada que será ejecutado con los valores '' sean cuales sean utilizados durante la creación. También se siente incómodo usar la primera iteración del ciclo para la creación –

+0

Así es como se diseñó la API, supongo, al menos eso es lo que obtuve leyendo los documentos y usándolos en uno de mis proyectos.La API espera que usted cree su objeto de consulta cuando necesite usarlo, y luego se dará cuenta si necesita preparar una declaración o no, dependiendo de si ya sabe sobre lo que pone en 'texto'. –

0

Puede utilizar pg-prepared para ello:

var prep = require('pg-prepared') 

// First prepare statement without binding parameters 
var item = prep('select id from mytable where id=${id}') 

// Then execute the query and bind parameters in loop 
for (i in [1,2,3]) { 
    client.query(item({id: i}), function(err, result) {...}) 
} 
+0

'pg-prepared' hace algo diferente de lo que OP está pidiendo. le da la capacidad de usar marcadores de posición con nombre en las consultas. –

+0

OP quiere crear declaraciones preparadas sin valores de parámetros vinculantes en la creación. Esto es lo que sucede en el ejemplo con la preparación de pg. Primero crea la declaración sin enlazar los valores de los parámetros y la almacena en var item. Entonces lo llamas con los parámetros. Así que OP puede usar esto creando la declaración sin vinculación de variables y luego llamarla con los valores de los parámetros en el ciclo. – pihvi

+1

en su caso, la * base de datos * tiene que preparar la consulta una y otra vez. lo que OP quiere es aliviar el DB preparando el stmt solo una vez. Dependiendo de la respuesta aceptada, pg-prepared podría llegar a esto si estuviera dando un atributo único de "nombre" a la consulta - cf https://github.com/brianc/node-postgres/wiki/Prepared-Statements –

Cuestiones relacionadas