1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
|
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>30.9.Error Handling</title>
<link rel="stylesheet" href="stylesheet.css" type="text/css">
<link rev="made" href="pgsql-docs@postgresql.org">
<meta name="generator" content="DocBook XSL Stylesheets V1.70.0">
<link rel="start" href="index.html" title="PostgreSQL 8.1.4 Documentation">
<link rel="up" href="ecpg.html" title="Chapter30.ECPG - Embedded SQL in C">
<link rel="prev" href="ecpg-descriptors.html" title="30.8.Using SQL Descriptor Areas">
<link rel="next" href="ecpg-include.html" title="30.10.Including Files">
<link rel="copyright" href="ln-legalnotice.html" title="Legal Notice">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="ecpg-errors"></a>30.9.Error Handling</h2></div></div></div>
<p> This section describes how you can handle exceptional conditions
and warnings in an embedded SQL program. There are several
nonexclusive facilities for this.
</p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="id690723"></a>30.9.1.Setting Callbacks</h3></div></div></div>
<p> One simple method to catch errors and warnings is to set a
specific action to be executed whenever a particular condition
occurs. In general:
</p>
<pre class="programlisting">EXEC SQL WHENEVER <em class="replaceable"><code>condition</code></em> <em class="replaceable"><code>action</code></em>;</pre>
<p>
</p>
<p> <em class="replaceable"><code>condition</code></em> can be one of the following:
</p>
<div class="variablelist"><dl>
<dt><span class="term"><code class="literal">SQLERROR</code></span></dt>
<dd><p> The specified action is called whenever an error occurs during
the execution of an SQL statement.
</p></dd>
<dt><span class="term"><code class="literal">SQLWARNING</code></span></dt>
<dd><p> The specified action is called whenever a warning occurs
during the execution of an SQL statement.
</p></dd>
<dt><span class="term"><code class="literal">NOT FOUND</code></span></dt>
<dd><p> The specified action is called whenever an SQL statement
retrieves or affects zero rows. (This condition is not an
error, but you might be interested in handling it specially.)
</p></dd>
</dl></div>
<p>
</p>
<p> <em class="replaceable"><code>action</code></em> can be one of the following:
</p>
<div class="variablelist"><dl>
<dt><span class="term"><code class="literal">CONTINUE</code></span></dt>
<dd><p> This effectively means that the condition is ignored. This is
the default.
</p></dd>
<dt>
<span xmlns="http://www.w3.org/TR/xhtml1/transitional" class="term"><code xmlns="" class="literal">GOTO <em class="replaceable"><code>label</code></em></code></span><br xmlns="http://www.w3.org/TR/xhtml1/transitional"></br><span class="term"><code class="literal">GO TO <em class="replaceable"><code>label</code></em></code></span>
</dt>
<dd><p> Jump to the specified label (using a C <code class="literal">goto</code>
statement).
</p></dd>
<dt><span class="term"><code class="literal">SQLPRINT</code></span></dt>
<dd><p> Print a message to standard error. This is useful for simple
programs or during prototyping. The details of the message
cannot be configured.
</p></dd>
<dt><span class="term"><code class="literal">STOP</code></span></dt>
<dd><p> Call <code class="literal">exit(1)</code>, which will terminate the
program.
</p></dd>
<dt><span class="term"><code class="literal">BREAK</code></span></dt>
<dd><p> Execute the C statement <code class="literal">break</code>. This should
only be used in loops or <code class="literal">switch</code> statements.
</p></dd>
<dt>
<span xmlns="http://www.w3.org/TR/xhtml1/transitional" class="term"><code xmlns="" class="literal">CALL <em class="replaceable"><code>name</code></em> (<em class="replaceable"><code>args</code></em>)</code></span><br xmlns="http://www.w3.org/TR/xhtml1/transitional"></br><span class="term"><code class="literal">DO <em class="replaceable"><code>name</code></em> (<em class="replaceable"><code>args</code></em>)</code></span>
</dt>
<dd><p> Call the specified C functions with the specified arguments.
</p></dd>
</dl></div>
<p>
The SQL standard only provides for the actions
<code class="literal">CONTINUE</code> and <code class="literal">GOTO</code> (and
<code class="literal">GO TO</code>).
</p>
<p> Here is an example that you might want to use in a simple program.
It prints a simple message when a warning occurs and aborts the
program when an error happens.
</p>
<pre class="programlisting">EXEC SQL WHENEVER SQLWARNING SQLPRINT;
EXEC SQL WHENEVER SQLERROR STOP;</pre>
<p>
</p>
<p> The statement <code class="literal">EXEC SQL WHENEVER</code> is a directive
of the SQL preprocessor, not a C statement. The error or warning
actions that it sets apply to all embedded SQL statements that
appear below the point where the handler is set, unless a
different action was set for the same condition between the first
<code class="literal">EXEC SQL WHENEVER</code> and the SQL statement causing
the condition, regardless of the flow of control in the C program.
So neither of the two following C program excerpts will have the
desired effect.
</p>
<pre class="programlisting">/*
* WRONG
*/
int main(int argc, char *argv[])
{
...
if (verbose) {
EXEC SQL WHENEVER SQLWARNING SQLPRINT;
}
...
EXEC SQL SELECT ...;
...
}</pre>
<p>
</p>
<pre class="programlisting">/*
* WRONG
*/
int main(int argc, char *argv[])
{
...
set_error_handler();
...
EXEC SQL SELECT ...;
...
}
static void set_error_handler(void)
{
EXEC SQL WHENEVER SQLERROR STOP;
}</pre>
<p>
</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="id691022"></a>30.9.2.sqlca</h3></div></div></div>
<p> For more powerful error handling, the embedded SQL interface
provides a global variable with the name <code class="varname">sqlca</code>
that has the following structure:
</p>
<pre class="programlisting">struct
{
char sqlcaid[8];
long sqlabc;
long sqlcode;
struct
{
int sqlerrml;
char sqlerrmc[70];
} sqlerrm;
char sqlerrp[8];
long sqlerrd[6];
char sqlwarn[8];
char sqlstate[5];
} sqlca;</pre>
<p>
(In a multithreaded program, every thread automatically gets its
own copy of <code class="varname">sqlca</code>. This works similarly to the
handling of the standard C global variable
<code class="varname">errno</code>.)
</p>
<p> <code class="varname">sqlca</code> covers both warnings and errors. If
multiple warnings or errors occur during the execution of a
statement, then <code class="varname">sqlca</code> will only contain
information about the last one.
</p>
<p> If no error occurred in the last <acronym class="acronym">SQL</acronym> statement,
<code class="literal">sqlca.sqlcode</code> will be 0 and
<code class="literal">sqlca.sqlstate</code> will be
<code class="literal">"00000"</code>. If a warning or error occurred, then
<code class="literal">sqlca.sqlcode</code> will be negative and
<code class="literal">sqlca.sqlstate</code> will be different from
<code class="literal">"00000"</code>. A positive
<code class="literal">sqlca.sqlcode</code> indicates a harmless condition,
such as that the last query returned zero rows.
<code class="literal">sqlcode</code> and <code class="literal">sqlstate</code> are two
different error code schemes; details appear below.
</p>
<p> If the last SQL statement was successful, then
<code class="literal">sqlca.sqlerrd[1]</code> contains the OID of the
processed row, if applicable, and
<code class="literal">sqlca.sqlerrd[2]</code> contains the number of
processed or returned rows, if applicable to the command.
</p>
<p> In case of an error or warning,
<code class="literal">sqlca.sqlerrm.sqlerrmc</code> will contain a string
that describes the error. The field
<code class="literal">sqlca.sqlerrm.sqlerrml</code> contains the length of
the error message that is stored in
<code class="literal">sqlca.sqlerrm.sqlerrmc</code> (the result of
<code class="function">strlen()</code>, not really interesting for a C
programmer). Note that some messages are too long to fit in the
fixed-size <code class="literal">sqlerrmc</code> array; they will be truncated.
</p>
<p> In case of a warning, <code class="literal">sqlca.sqlwarn[2]</code> is set
to <code class="literal">W</code>. (In all other cases, it is set to
something different from <code class="literal">W</code>.) If
<code class="literal">sqlca.sqlwarn[1]</code> is set to
<code class="literal">W</code>, then a value was truncated when it was
stored in a host variable. <code class="literal">sqlca.sqlwarn[0]</code> is
set to <code class="literal">W</code> if any of the other elements are set
to indicate a warning.
</p>
<p> The fields <code class="structfield">sqlcaid</code>,
<code class="structfield">sqlcabc</code>,
<code class="structfield">sqlerrp</code>, and the remaining elements of
<code class="structfield">sqlerrd</code> and
<code class="structfield">sqlwarn</code> currently contain no useful
information.
</p>
<p> The structure <code class="varname">sqlca</code> 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.
</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="id691292"></a>30.9.3.<code class="literal">SQLSTATE</code> vs <code class="literal">SQLCODE</code></h3></div></div></div>
<p> The fields <code class="literal">sqlca.sqlstate</code> and
<code class="literal">sqlca.sqlcode</code> are two different schemes that
provide error codes. Both are derived from the SQL standard, but
<code class="literal">SQLCODE</code> 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
<code class="literal">SQLSTATE</code>.
</p>
<p> <code class="literal">SQLSTATE</code> is a five-character array. The five
characters contain digits or upper-case letters that represent
codes of various error and warning conditions.
<code class="literal">SQLSTATE</code> has a hierarchical scheme: the first
two characters indicate the general class of the condition, the
last three characters indicate a subclass of the general
condition. A successful state is indicated by the code
<code class="literal">00000</code>. The <code class="literal">SQLSTATE</code> codes are for
the most part defined in the SQL standard. The
<span class="productname">PostgreSQL</span> server natively supports
<code class="literal">SQLSTATE</code> error codes; therefore a high degree
of consistency can be achieved by using this error code scheme
throughout all applications. For further information see
<a href="errcodes-appendix.html" title="AppendixA.PostgreSQL Error Codes">AppendixA, <i><span class="productname">PostgreSQL</span> Error Codes</i></a>.
</p>
<p> <code class="literal">SQLCODE</code>, the deprecated error code scheme, is a
simple integer. A value of 0 indicates success, a positive value
indicates success with additional information, a negative value
indicates an error. The SQL standard only defines the positive
value +100, which indicates that the last command returned or
affected zero rows, and no specific negative values. Therefore,
this scheme can only achieve poor portability and does not have a
hierarchical code assignment. Historically, the embedded SQL
processor for <span class="productname">PostgreSQL</span> has assigned
some specific <code class="literal">SQLCODE</code> values for its use, which
are listed below with their numeric value and their symbolic name.
Remember that these are not portable to other SQL implementations.
To simplify the porting of applications to the
<code class="literal">SQLSTATE</code> scheme, the corresponding
<code class="literal">SQLSTATE</code> is also listed. There is, however, no
one-to-one or one-to-many mapping between the two schemes (indeed
it is many-to-many), so you should consult the global
<code class="literal">SQLSTATE</code> listing in <a href="errcodes-appendix.html" title="AppendixA.PostgreSQL Error Codes">AppendixA, <i><span class="productname">PostgreSQL</span> Error Codes</i></a>
in each case.
</p>
<p> These are the assigned <code class="literal">SQLCODE</code> values:
</p>
<div class="variablelist"><dl>
<dt><span class="term">-12 (<code class="symbol">ECPG_OUT_OF_MEMORY</code>)</span></dt>
<dd><p> Indicates that your virtual memory is exhausted. (SQLSTATE
YE001)
</p></dd>
<dt><span class="term">-200 (<code class="symbol">ECPG_UNSUPPORTED</code>)</span></dt>
<dd><p> Indicates the preprocessor has generated something that the
library does not know about. Perhaps you are running
incompatible versions of the preprocessor and the
library. (SQLSTATE YE002)
</p></dd>
<dt><span class="term">-201 (<code class="symbol">ECPG_TOO_MANY_ARGUMENTS</code>)</span></dt>
<dd><p> This means that the command specified more host variables than
the command expected. (SQLSTATE 07001 or 07002)
</p></dd>
<dt><span class="term">-202 (<code class="symbol">ECPG_TOO_FEW_ARGUMENTS</code>)</span></dt>
<dd><p> This means that the command specified fewer host variables than
the command expected. (SQLSTATE 07001 or 07002)
</p></dd>
<dt><span class="term">-203 (<code class="symbol">ECPG_TOO_MANY_MATCHES</code>)</span></dt>
<dd><p> This means a query has returned multiple rows but the statement
was only prepared to store one result row (for example, because
the specified variables are not arrays). (SQLSTATE 21000)
</p></dd>
<dt><span class="term">-204 (<code class="symbol">ECPG_INT_FORMAT</code>)</span></dt>
<dd><p> The host variable is of type <code class="type">int</code> and the datum in
the database is of a different type and contains a value that
cannot be interpreted as an <code class="type">int</code>. The library uses
<code class="function">strtol()</code> for this conversion. (SQLSTATE
42804)
</p></dd>
<dt><span class="term">-205 (<code class="symbol">ECPG_UINT_FORMAT</code>)</span></dt>
<dd><p> The host variable is of type <code class="type">unsigned int</code> and the
datum in the database is of a different type and contains a
value that cannot be interpreted as an <code class="type">unsigned
int</code>. The library uses <code class="function">strtoul()</code>
for this conversion. (SQLSTATE 42804)
</p></dd>
<dt><span class="term">-206 (<code class="symbol">ECPG_FLOAT_FORMAT</code>)</span></dt>
<dd><p> The host variable is of type <code class="type">float</code> and the datum
in the database is of another type and contains a value that
cannot be interpreted as a <code class="type">float</code>. The library
uses <code class="function">strtod()</code> for this conversion.
(SQLSTATE 42804)
</p></dd>
<dt><span class="term">-207 (<code class="symbol">ECPG_CONVERT_BOOL</code>)</span></dt>
<dd><p> This means the host variable is of type <code class="type">bool</code> and
the datum in the database is neither <code class="literal">'t'</code> nor
<code class="literal">'f'</code>. (SQLSTATE 42804)
</p></dd>
<dt><span class="term">-208 (<code class="symbol">ECPG_EMPTY</code>)</span></dt>
<dd><p> The statement sent to the <span class="productname">PostgreSQL</span>
server was empty. (This cannot normally happen in an embedded
SQL program, so it may point to an internal error.) (SQLSTATE
YE002)
</p></dd>
<dt><span class="term">-209 (<code class="symbol">ECPG_MISSING_INDICATOR</code>)</span></dt>
<dd><p> A null value was returned and no null indicator variable was
supplied. (SQLSTATE 22002)
</p></dd>
<dt><span class="term">-210 (<code class="symbol">ECPG_NO_ARRAY</code>)</span></dt>
<dd><p> An ordinary variable was used in a place that requires an
array. (SQLSTATE 42804)
</p></dd>
<dt><span class="term">-211 (<code class="symbol">ECPG_DATA_NOT_ARRAY</code>)</span></dt>
<dd><p> The database returned an ordinary variable in a place that
requires array value. (SQLSTATE 42804)
</p></dd>
<dt><span class="term">-220 (<code class="symbol">ECPG_NO_CONN</code>)</span></dt>
<dd><p> The program tried to access a connection that does not exist.
(SQLSTATE 08003)
</p></dd>
<dt><span class="term">-221 (<code class="symbol">ECPG_NOT_CONN</code>)</span></dt>
<dd><p> The program tried to access a connection that does exist but is
not open. (This is an internal error.) (SQLSTATE YE002)
</p></dd>
<dt><span class="term">-230 (<code class="symbol">ECPG_INVALID_STMT</code>)</span></dt>
<dd><p> The statement you are trying to use has not been prepared.
(SQLSTATE 26000)
</p></dd>
<dt><span class="term">-240 (<code class="symbol">ECPG_UNKNOWN_DESCRIPTOR</code>)</span></dt>
<dd><p> The descriptor specified was not found. The statement you are
trying to use has not been prepared. (SQLSTATE 33000)
</p></dd>
<dt><span class="term">-241 (<code class="symbol">ECPG_INVALID_DESCRIPTOR_INDEX</code>)</span></dt>
<dd><p> The descriptor index specified was out of range. (SQLSTATE
07009)
</p></dd>
<dt><span class="term">-242 (<code class="symbol">ECPG_UNKNOWN_DESCRIPTOR_ITEM</code>)</span></dt>
<dd><p> An invalid descriptor item was requested. (This is an internal
error.) (SQLSTATE YE002)
</p></dd>
<dt><span class="term">-243 (<code class="symbol">ECPG_VAR_NOT_NUMERIC</code>)</span></dt>
<dd><p> During the execution of a dynamic statement, the database
returned a numeric value and the host variable was not numeric.
(SQLSTATE 07006)
</p></dd>
<dt><span class="term">-244 (<code class="symbol">ECPG_VAR_NOT_CHAR</code>)</span></dt>
<dd><p> During the execution of a dynamic statement, the database
returned a non-numeric value and the host variable was numeric.
(SQLSTATE 07006)
</p></dd>
<dt><span class="term">-400 (<code class="symbol">ECPG_PGSQL</code>)</span></dt>
<dd><p> Some error caused by the <span class="productname">PostgreSQL</span>
server. The message contains the error message from the
<span class="productname">PostgreSQL</span> server.
</p></dd>
<dt><span class="term">-401 (<code class="symbol">ECPG_TRANS</code>)</span></dt>
<dd><p> The <span class="productname">PostgreSQL</span> server signaled that
we cannot start, commit, or rollback the transaction.
(SQLSTATE 08007)
</p></dd>
<dt><span class="term">-402 (<code class="symbol">ECPG_CONNECT</code>)</span></dt>
<dd><p> The connection attempt to the database did not succeed.
(SQLSTATE 08001)
</p></dd>
<dt><span class="term">100 (<code class="symbol">ECPG_NOT_FOUND</code>)</span></dt>
<dd><p> This is a harmless condition indicating that the last command
retrieved or processed zero rows, or that you are at the end of
the cursor. (SQLSTATE 02000)
</p></dd>
</dl></div>
<p>
</p>
</div>
</div></body>
</html>
|