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 = "postgres";
sqlda2->sqlvar[0].sqllen = 8;
intval = 1;
sqlda2->sqlvar[1].sqltype = ECPGt_int;
sqlda2->sqlvar[1].sqldata = (char *)&intval;
sqlda2->sqlvar[1].sqllen = sizeof(intval);
</programlisting>
</para>
<para>
After setting up the input SQLDA, open a cursor with the input
SQLDA.
<programlisting>
/* Open a cursor with input parameters. */
EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;
</programlisting>
</para>
<para>
Fetch rows into the output SQLDA from the opened cursor.
(Generally, you have to call <command>FETCH</command> repeatedly
in the loop, to fetch all rows in the result set.)
<programlisting>
while (1)
{
sqlda_t *cur_sqlda;
/* Assign descriptor to the cursor */
EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1;
</programlisting>
</para>
<para>
Next, retrieve the fetched records from the SQLDA, by following
the linked list of the <type>sqlda_t</type> structure.
<programlisting>
for (cur_sqlda = sqlda1 ;
cur_sqlda != NULL ;
cur_sqlda = cur_sqlda->desc_next)
{
...
</programlisting>
</para>
<para>
Read each columns in the first record. The number of columns is
stored in <structfield>sqld</structfield>, the actual data of the first
column is stored in <literal>sqlvar[0]</literal>, both members of
the <type>sqlda_t</type> structure.
<programlisting>
/* Print every column in a row. */
for (i = 0; i < sqlda1->sqld; i++)
{
sqlvar_t v = sqlda1->sqlvar[i];
char *sqldata = v.sqldata;
short sqllen = v.sqllen;
strncpy(name_buf, v.sqlname.data, v.sqlname.length);
name_buf[v.sqlname.length] = '\0';
</programlisting>
</para>
<para>
Now, the column data is stored in the variable <varname>v</varname>.
Copy every datum into host variables, looking
at <literal>v.sqltype</literal> for the type of the column.
<programlisting>
switch (v.sqltype) {
int intval;
double doubleval;
unsigned long long int longlongval;
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;
...
default:
...
}
printf("%s = %s (type: %d)\n", name_buf, var_buf, v.sqltype);
}
</programlisting>
</para>
<para>
Close the cursor after processing all of records, and disconnect
from the database.
<programlisting>
EXEC SQL CLOSE cur1;