<literal>sqlca.sqlerrm.sqlerrml</literal> contains the length of
the error message that is stored in
<literal>sqlca.sqlerrm.sqlerrmc</literal> (the result of
<function>strlen()</function>, not really interesting for a C
programmer). Note that some messages are too long to fit in the
fixed-size <literal>sqlerrmc</literal> array; they will be truncated.
</para>
<para>
In case of a warning, <literal>sqlca.sqlwarn[2]</literal> is set
to <literal>W</literal>. (In all other cases, it is set to
something different from <literal>W</literal>.) If
<literal>sqlca.sqlwarn[1]</literal> is set to
<literal>W</literal>, then a value was truncated when it was
stored in a host variable. <literal>sqlca.sqlwarn[0]</literal> is
set to <literal>W</literal> if any of the other elements are set
to indicate a warning.
</para>
<para>
The fields <structfield>sqlcaid</structfield>,
<structfield>sqlabc</structfield>,
<structfield>sqlerrp</structfield>, and the remaining elements of
<structfield>sqlerrd</structfield> and
<structfield>sqlwarn</structfield> currently contain no useful
information.
</para>
<para>
The structure <varname>sqlca</varname> is not defined in the SQL
standard, but is implemented in several other SQL database
systems. The definitions are similar at the core, but if you want
to write portable applications, then you should investigate the
different implementations carefully.
</para>
<para>
Here is one example that combines the use of <literal>WHENEVER</literal>
and <varname>sqlca</varname>, printing out the contents
of <varname>sqlca</varname> when an error occurs. This is perhaps
useful for debugging or prototyping applications, before
installing a more <quote>user-friendly</quote> error handler.
<programlisting>
EXEC SQL WHENEVER SQLERROR CALL print_sqlca();
void
print_sqlca()
{
fprintf(stderr, "==== sqlca ====\n");
fprintf(stderr, "sqlcode: %ld\n", sqlca.sqlcode);
fprintf(stderr, "sqlerrm.sqlerrml: %d\n", sqlca.sqlerrm.sqlerrml);
fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);
fprintf(stderr, "sqlerrd: %ld %ld %ld %ld %ld %ld\n", sqlca.sqlerrd[0],sqlca.sqlerrd[1],sqlca.sqlerrd[2],
sqlca.sqlerrd[3],sqlca.sqlerrd[4],sqlca.sqlerrd[5]);
fprintf(stderr, "sqlwarn: %d %d %d %d %d %d %d %d\n", sqlca.sqlwarn[0], sqlca.sqlwarn[1], sqlca.sqlwarn[2],
sqlca.sqlwarn[3], sqlca.sqlwarn[4], sqlca.sqlwarn[5],
sqlca.sqlwarn[6], sqlca.sqlwarn[7]);
fprintf(stderr, "sqlstate: %5s\n", sqlca.sqlstate);
fprintf(stderr, "===============\n");
}
</programlisting>
The result could look as follows (here an error due to a
misspelled table name):
<screen>
==== sqlca ====
sqlcode: -400
sqlerrm.sqlerrml: 49
sqlerrm.sqlerrmc: relation "pg_databasep" does not exist on line 38
sqlerrd: 0 0 0 0 0 0
sqlwarn: 0 0 0 0 0 0 0 0
sqlstate: 42P01
===============
</screen>
</para>
</sect2>
<sect2 id="ecpg-sqlstate-sqlcode">
<title><literal>SQLSTATE</literal> vs. <literal>SQLCODE</literal></title>
<para>
The fields <literal>sqlca.sqlstate</literal> and
<literal>sqlca.sqlcode</literal> are two different schemes that
provide error codes. Both are derived from the SQL standard, but
<literal>SQLCODE</literal> has been marked deprecated in the SQL-92
edition of the standard and has been dropped in later editions.
Therefore, new applications are strongly encouraged to use
<literal>SQLSTATE</literal>.
</para>
<para>
<literal>SQLSTATE</literal> is a five-character array. The five
characters contain digits or upper-case letters that represent
codes of various error and warning conditions.
<literal>SQLSTATE</literal> has a hierarchical scheme: