Existují dva způsoby, jak to zvládnout. První je připravit řetězec s vloženými hodnotami. Druhým je použití parametrů dotazu, za které můžete dosazovat hodnoty samostatně.
Pro první metodu můžete použít funkci jako snprintf k přípravě příkazu, který odešlete na server. Například:
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 */
}
Po tomto bufferu bude obsahovat SQL dotaz včetně aktuální hodnoty proměnné id.
Všimněte si, že je třeba zkontrolovat návratovou hodnotu z snprintf, abyste zjistili, zda nedošlo k přetečení vyrovnávací paměti.
Všimněte si také, že když je do příkazu vkládán řetězec, musíte zajistit, aby řetězec neobsahoval žádné uvozovky nebo jiné speciální znaky. Pokud řetězec pochází mimo váš program, např. Z uživatelského vstupu pak jeho nesprávné citování zanechá velkou díru, kterou by někdo mohl vložit nějaké škodlivé SQL. libpq poskytuje PQescapeLiteral funkce pro toto.
Další metodou, která je ve většině případů výhodnější, je předat serveru SQL příkaz a parametry samostatně. Můžete to udělat například pomocí PQexecParams libpq functoin. Váš řetězec SQL by vypadal takto:
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 */
);
Tato funkce umožňuje zadat parametry a/nebo získat výsledky buď v textovém nebo binárním formátu. Pro jednoduchost můj příklad výše předpokládá textový formát pro oba.
Variantou je použití připravených příkazů. V tomto případě provedete dvě samostatná volání libpq:
-
Zavolejte PQprepare, kterému předáte svůj SQL příkaz s hodnotami parametrů $1, $2 atd., jako v mém příkladu výše. Tím se vrátí popisovač příkazu.
-
Zavolejte PQexecPrepared, kterému předáte popisovač příkazu a také samotné parametry, zadané podobným způsobem jako PQexecParams.
Výhodou použití dvou kroků, jako je tento, je, že můžete výpis připravit jednou a provést jej mnohokrát, což snižuje režii serveru spojenou s jeho analýzou a plánováním dotazu.