memory for an SQLDA, and set the number of input
parameters in <structfield>sqln</structfield>, a member variable of
the <type>sqlda_t</type> structure. When two or more input
parameters are required for the prepared query, the application
has to allocate additional memory space which is calculated by
(nr. of params - 1) * sizeof(sqlvar_t). The example shown here
allocates memory space for two input parameters.
<programlisting>
sqlda_t *sqlda2;
sqlda2 = (sqlda_t *) malloc(sizeof(sqlda_t) + sizeof(sqlvar_t));
memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t));
sqlda2->sqln = 2; /* number of input variables */
</programlisting>
</para>
<para>
After memory allocation, store the parameter values into the
<literal>sqlvar[]</literal> array. (This is same array used for
retrieving column values when the SQLDA is receiving a result
set.) In this example, the input parameters
are <literal>"postgres"</literal>, having a string type,
and <literal>1</literal>, having an integer type.
<programlisting>
sqlda2->sqlvar[0].sqltype = ECPGt_char;
sqlda2->sqlvar[0].sqldata = "postgres";
sqlda2->sqlvar[0].sqllen = 8;
int intval = 1;
sqlda2->sqlvar[1].sqltype = ECPGt_int;
sqlda2->sqlvar[1].sqldata = (char *) &intval;
sqlda2->sqlvar[1].sqllen = sizeof(intval);
</programlisting>
</para>
<para>
By opening a cursor and specifying the SQLDA that was set up
beforehand, the input parameters are passed to the prepared
statement.
<programlisting>
EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;
</programlisting>
</para>
<para>
Finally, after using input SQLDAs, the allocated memory space
must be freed explicitly, unlike SQLDAs used for receiving query
results.
<programlisting>
free(sqlda2);
</programlisting>
</para>
</sect3>
<sect3 id="ecpg-sqlda-example">
<title>A Sample Application Using SQLDA</title>
<para>
Here is an example program, which describes how to fetch access
statistics of the databases, specified by the input parameters,
from the system catalogs.
</para>
<para>
This application joins two system tables, pg_database and
pg_stat_database on the database OID, and also fetches and shows
the database statistics which are retrieved by two input
parameters (a database <literal>postgres</literal>, and OID <literal>1</literal>).
</para>
<para>
First, declare an SQLDA for input and an SQLDA for output.
<programlisting>
EXEC SQL include sqlda.h;
sqlda_t *sqlda1; /* an output descriptor */
sqlda_t *sqlda2; /* an input descriptor */
</programlisting>
</para>
<para>
Next, connect to the database, prepare a statement, and declare a
cursor for the prepared statement.
<programlisting>
int
main(void)
{
EXEC SQL BEGIN DECLARE SECTION;
char query[1024] = "SELECT d.oid,* FROM pg_database d, pg_stat_database s WHERE d.oid=s.datid AND ( d.datname=? OR d.oid=? )";
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 :query;
EXEC SQL DECLARE cur1 CURSOR FOR stmt1;
</programlisting>
</para>
<para>
Next, put some values in the input SQLDA for the input
parameters. Allocate memory for the input SQLDA, and set the
number of input parameters to <literal>sqln</literal>. Store
type, value, and value length into <literal>sqltype</literal>,
<literal>sqldata</literal>, and <literal>sqllen</literal> in the
<literal>sqlvar</literal> structure.
<programlisting>
/* Create SQLDA structure for input parameters. */
sqlda2 = (sqlda_t *) malloc(sizeof(sqlda_t) + sizeof(sqlvar_t));
memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t));
sqlda2->sqln = 2; /* number of input variables */
sqlda2->sqlvar[0].sqltype = ECPGt_char;
sqlda2->sqlvar[0].sqldata