Hay dos formas de manejar esto. El primero es preparar la cadena con los valores insertados en ella. El segundo es usar parámetros de consulta para los cuales puede sustituir valores por separado.
Para el primer método, puede usar una función como snprintf para preparar el comando que enviará al servidor. Por ejemplo:
char buffer[512];
int num=snprintf(buffer, sizeof(buffer),
"SELECT name FROM MYTABLE WHERE id=%d", id);
if (num>sizeof(buffer)) {
/* error: buffer was too small */
}
Después de este búfer, contendrá la consulta SQL, incluido el valor real de la variable id.
Tenga en cuenta la necesidad de verificar el valor de retorno de snprintf para ver si el búfer se desbordó.
También tenga en cuenta que cuando se coloca una cadena en el comando, debe asegurarse de que la cadena no contenga comillas u otros caracteres especiales. Si la cadena proviene de fuera de su programa, por ejemplo. A partir de la entrada del usuario, el hecho de no citarlo correctamente deja un gran agujero a través del cual alguien podría inyectar SQL malicioso. libpq proporciona el PQescapeLiteral función para esto.
El otro método, que es preferible en la mayoría de los casos, es pasar el comando SQL y los parámetros al servidor por separado. Por ejemplo, puede hacer esto usando PQexecParams Función libpq. Su cadena SQL se vería así:
PGresult r = PQexecParams(conn, /* Connection to database */
"SELECT name FROM mytable WHERE id=$1",
1, /* Number of parameters */
NULL, /* NULL means server should figure out the parameter types */
params, /* Pointer to array of strings containing parameters */
NULL, /* Not needed unless binary format used */
NULL, /* Not needed unless binary format used */
0 /* Result to come back in text format */
);
Esta función le permite proporcionar parámetros y/u obtener resultados en formato de texto o binario. Para simplificar, mi ejemplo anterior asume formato de texto para ambos.
Una variación de esto es usar declaraciones preparadas. En este caso, realiza dos llamadas separadas a libpq:
-
Llame a PQprepare, al que pasa su instrucción SQL con valores de parámetro $1, $2, etc., según mi ejemplo anterior. Esto devolverá un identificador de declaración.
-
Llame a PQexecPrepared, al que le pasa el identificador de sentencia y también los propios parámetros, especificados de manera similar a PQexecParams.
La ventaja de usar dos pasos como este es que puede preparar la declaración una vez y ejecutarla muchas veces, lo que reduce la cantidad de sobrecarga del servidor asociada con el análisis y la planificación de la consulta.