structure.</simpara></step>
<step><simpara>Repeat above as you need.</simpara></step>
</procedure>
<para>
Here is an example retrieving a result set through an SQLDA.
</para>
<para>
First, declare a <type>sqlda_t</type> structure to receive the result set.
<programlisting>
sqlda_t *sqlda1;
</programlisting>
</para>
<para>
Next, specify the SQLDA in a command. This is
a <command>FETCH</command> command example.
<programlisting>
EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1;
</programlisting>
</para>
<para>
Run a loop following the linked list to retrieve the rows.
<programlisting>
sqlda_t *cur_sqlda;
for (cur_sqlda = sqlda1;
cur_sqlda != NULL;
cur_sqlda = cur_sqlda->desc_next)
{
...
}
</programlisting>
</para>
<para>
Inside the loop, run another loop to retrieve each column data
(<type>sqlvar_t</type> structure) of the row.
<programlisting>
for (i = 0; i < cur_sqlda->sqld; i++)
{
sqlvar_t v = cur_sqlda->sqlvar[i];
char *sqldata = v.sqldata;
short sqllen = v.sqllen;
...
}
</programlisting>
</para>
<para>
To get a column value, check the <structfield>sqltype</structfield> value,
a member of the <type>sqlvar_t</type> structure. Then, switch
to an appropriate way, depending on the column type, to copy
data from the <structfield>sqlvar</structfield> field to a host variable.
<programlisting>
char var_buf[1024];
switch (v.sqltype)
{
case ECPGt_char:
memset(&var_buf, 0, sizeof(var_buf));
memcpy(&var_buf, sqldata, (sizeof(var_buf) <= sqllen ? sizeof(var_buf) - 1 : sqllen));
break;
case ECPGt_int: /* integer */
memcpy(&intval, sqldata, sqllen);
snprintf(var_buf, sizeof(var_buf), "%d", intval);
break;
...
}
</programlisting>
</para>
</sect3>
<sect3 id="ecpg-sqlda-input">
<title>Passing Query Parameters Using an SQLDA</title>
<procedure>
<para>
The general steps to use an SQLDA to pass input
parameters to a prepared query are:
</para>
<step><simpara>Create a prepared query (prepared statement)</simpara></step>
<step><simpara>Declare an sqlda_t structure as an input SQLDA.</simpara></step>
<step><simpara>Allocate memory area (as sqlda_t structure) for the input SQLDA.</simpara></step>
<step><simpara>Set (copy) input values in the allocated memory.</simpara></step>
<step><simpara>Open a cursor with specifying the input SQLDA.</simpara></step>
</procedure>
<para>
Here is an example.
</para>
<para>
First, create a prepared statement.
<programlisting>
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 PREPARE stmt1 FROM :query;
</programlisting>
</para>
<para>
Next, allocate 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