PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Passando variáveis ​​C no comando SQL


Existem duas maneiras de lidar com isso. A primeira é preparar a string com os valores inseridos nela. A segunda é usar parâmetros de consulta para os quais você pode substituir valores separadamente.

Para o primeiro método, você pode usar uma função como snprintf para preparar o comando que você enviará ao servidor. Por exemplo:
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 */
}

Após este buffer conterá a consulta SQL incluindo o valor real da variável id.

Observe a necessidade de verificar o valor de retorno de snprintf para ver se o buffer estourou.

Observe também que quando uma string está sendo colocada no comando, você precisa garantir que a string não contenha aspas ou outros caracteres especiais. Se a string vier de fora do seu programa, por exemplo. A partir da entrada do usuário, a falha em citá-la corretamente deixa um grande buraco através do qual alguém pode injetar algum SQL malicioso. libpq fornece o PQescapeLiteral função para isso.

O outro método, que é preferível na maioria dos casos, é passar o comando SQL e os parâmetros para o servidor separadamente. Por exemplo, você pode fazer isso usando PQexecParams função libpq. Sua string SQL ficaria assim:
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 função permite fornecer parâmetros e/ou obter resultados em formato texto ou binário. Para simplificar, meu exemplo acima assume o formato de texto para ambos.

Uma variação disso é usar declarações preparadas. Nesse caso, você faz duas chamadas separadas para libpq:

  1. Chame PQprepare, para o qual você passa sua instrução SQL com valores de parâmetro $1, $2, etc, conforme meu exemplo acima. Isso retornará um identificador de instrução.

  2. Chame PQexecPrepared, para o qual você passa o identificador de instrução e também os próprios parâmetros, especificados de maneira semelhante a PQexecParams.

A vantagem de usar duas etapas como essa é que você pode preparar a instrução uma vez e executá-la várias vezes, o que reduz a quantidade de sobrecarga do servidor associada à análise e ao planejamento da consulta.