directly into the C source code, but there is a
facility that allows you to call arbitrary SQL statements that you
provide in a string variable.
</para>
<sect2 id="ecpg-dynamic-without-result">
<title>Executing Statements without a Result Set</title>
<para>
The simplest way to execute an arbitrary SQL statement is to use
the command <command>EXECUTE IMMEDIATE</command>. For example:
<programlisting>
EXEC SQL BEGIN DECLARE SECTION;
const char *stmt = "CREATE TABLE test1 (...);";
EXEC SQL END DECLARE SECTION;
EXEC SQL EXECUTE IMMEDIATE :stmt;
</programlisting>
<command>EXECUTE IMMEDIATE</command> can be used for SQL
statements that do not return a result set (e.g.,
DDL, <command>INSERT</command>, <command>UPDATE</command>,
<command>DELETE</command>). You cannot execute statements that
retrieve data (e.g., <command>SELECT</command>) this way. The
next section describes how to do that.
</para>
</sect2>
<sect2 id="ecpg-dynamic-input">
<title>Executing a Statement with Input Parameters</title>
<para>
A more powerful way to execute arbitrary SQL statements is to
prepare them once and execute the prepared statement as often as
you like. It is also possible to prepare a generalized version of
a statement and then execute specific versions of it by
substituting parameters. When preparing the statement, write
question marks where you want to substitute parameters later. For
example:
<programlisting>
EXEC SQL BEGIN DECLARE SECTION;
const char *stmt = "INSERT INTO test1 VALUES(?, ?);";
EXEC SQL END DECLARE SECTION;
EXEC SQL PREPARE mystmt FROM :stmt;
...
EXEC SQL EXECUTE mystmt USING 42, 'foobar';
</programlisting>
</para>
<para>
When you don't need the prepared statement anymore, you should
deallocate it:
<programlisting>
EXEC SQL DEALLOCATE PREPARE <replaceable>name</replaceable>;
</programlisting>
</para>
</sect2>
<sect2 id="ecpg-dynamic-with-result">
<title>Executing a Statement with a Result Set</title>
<para>
To execute an SQL statement with a single result row,
<command>EXECUTE</command> can be used. To save the result, add
an <literal>INTO</literal> clause.
<programlisting><![CDATA[
EXEC SQL BEGIN DECLARE SECTION;
const char *stmt = "SELECT a, b, c FROM test1 WHERE a > ?";
int v1, v2;
VARCHAR v3[50];
EXEC SQL END DECLARE SECTION;
EXEC SQL PREPARE mystmt FROM :stmt;
...
EXEC SQL EXECUTE mystmt INTO :v1, :v2, :v3 USING 37;
]]>
</programlisting>
An <command>EXECUTE</command> command can have an
<literal>INTO</literal> clause, a <literal>USING</literal> clause,
both, or neither.
</para>
<para>
If a query is expected to return more than one result row, a
cursor should be used, as in the following example.
(See <xref linkend="ecpg-cursors"/> for more details about the
cursor.)
<programlisting>
EXEC SQL BEGIN DECLARE SECTION;
char dbaname[128];
char datname[128];
char *stmt = "SELECT u.usename as dbaname, d.datname "
" FROM pg_database d, pg_user u "
" WHERE d.datdba = u.usesysid";
EXEC SQL END DECLARE SECTION;
EXEC SQL CONNECT TO testdb AS con1 USER testuser;
EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
EXEC SQL PREPARE stmt1 FROM :stmt;
EXEC SQL DECLARE cursor1 CURSOR FOR stmt1;
EXEC SQL OPEN cursor1;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
EXEC SQL FETCH cursor1 INTO :dbaname,:datname;
printf("dbaname=%s, datname=%s\n", dbaname, datname);
}
EXEC SQL CLOSE cursor1;
EXEC SQL COMMIT;
EXEC SQL DISCONNECT ALL;
</programlisting>
</para>
</sect2>
</sect1>
<sect1 id="ecpg-pgtypes">
<title>pgtypes Library</title>
<para>
The pgtypes library maps <productname>PostgreSQL</productname> database
types to C equivalents that can be used in C programs. It also offers
functions to do basic calculations with those types within C, i.e., without
the help of the <productname>PostgreSQL</productname>