4 34.8.1. Setting Callbacks
6 34.8.3. SQLSTATE vs. SQLCODE
8 This section describes how you can handle exceptional conditions and
9 warnings in an embedded SQL program. There are two nonexclusive
11 * Callbacks can be configured to handle warning and error conditions
12 using the WHENEVER command.
13 * Detailed information about the error or warning can be obtained
14 from the sqlca variable.
16 34.8.1. Setting Callbacks #
18 One simple method to catch errors and warnings is to set a specific
19 action to be executed whenever a particular condition occurs. In
21 EXEC SQL WHENEVER condition action;
23 condition can be one of the following:
26 The specified action is called whenever an error occurs during
27 the execution of an SQL statement.
30 The specified action is called whenever a warning occurs during
31 the execution of an SQL statement.
34 The specified action is called whenever an SQL statement
35 retrieves or affects zero rows. (This condition is not an error,
36 but you might be interested in handling it specially.)
38 action can be one of the following:
41 This effectively means that the condition is ignored. This is
46 Jump to the specified label (using a C goto statement).
49 Print a message to standard error. This is useful for simple
50 programs or during prototyping. The details of the message
54 Call exit(1), which will terminate the program.
57 Execute the C statement break. This should only be used in loops
61 Execute the C statement continue. This should only be used in
62 loops statements. if executed, will cause the flow of control to
63 return to the top of the loop.
67 Call the specified C functions with the specified arguments.
68 (This use is different from the meaning of CALL and DO in the
69 normal PostgreSQL grammar.)
71 The SQL standard only provides for the actions CONTINUE and GOTO (and
74 Here is an example that you might want to use in a simple program. It
75 prints a simple message when a warning occurs and aborts the program
76 when an error happens:
77 EXEC SQL WHENEVER SQLWARNING SQLPRINT;
78 EXEC SQL WHENEVER SQLERROR STOP;
80 The statement EXEC SQL WHENEVER is a directive of the SQL preprocessor,
81 not a C statement. The error or warning actions that it sets apply to
82 all embedded SQL statements that appear below the point where the
83 handler is set, unless a different action was set for the same
84 condition between the first EXEC SQL WHENEVER and the SQL statement
85 causing the condition, regardless of the flow of control in the C
86 program. So neither of the two following C program excerpts will have
91 int main(int argc, char *argv[])
95 EXEC SQL WHENEVER SQLWARNING SQLPRINT;
105 int main(int argc, char *argv[])
114 static void set_error_handler(void)
116 EXEC SQL WHENEVER SQLERROR STOP;
121 For more powerful error handling, the embedded SQL interface provides a
122 global variable with the name sqlca (SQL communication area) that has
123 the following structure:
132 char sqlerrmc[SQLERRMC_LEN];
140 (In a multithreaded program, every thread automatically gets its own
141 copy of sqlca. This works similarly to the handling of the standard C
142 global variable errno.)
144 sqlca covers both warnings and errors. If multiple warnings or errors
145 occur during the execution of a statement, then sqlca will only contain
146 information about the last one.
148 If no error occurred in the last SQL statement, sqlca.sqlcode will be 0
149 and sqlca.sqlstate will be "00000". If a warning or error occurred,
150 then sqlca.sqlcode will be negative and sqlca.sqlstate will be
151 different from "00000". A positive sqlca.sqlcode indicates a harmless
152 condition, such as that the last query returned zero rows. sqlcode and
153 sqlstate are two different error code schemes; details appear below.
155 If the last SQL statement was successful, then sqlca.sqlerrd[1]
156 contains the OID of the processed row, if applicable, and
157 sqlca.sqlerrd[2] contains the number of processed or returned rows, if
158 applicable to the command.
160 In case of an error or warning, sqlca.sqlerrm.sqlerrmc will contain a
161 string that describes the error. The field sqlca.sqlerrm.sqlerrml
162 contains the length of the error message that is stored in
163 sqlca.sqlerrm.sqlerrmc (the result of strlen(), not really interesting
164 for a C programmer). Note that some messages are too long to fit in the
165 fixed-size sqlerrmc array; they will be truncated.
167 In case of a warning, sqlca.sqlwarn[2] is set to W. (In all other
168 cases, it is set to something different from W.) If sqlca.sqlwarn[1] is
169 set to W, then a value was truncated when it was stored in a host
170 variable. sqlca.sqlwarn[0] is set to W if any of the other elements are
171 set to indicate a warning.
173 The fields sqlcaid, sqlabc, sqlerrp, and the remaining elements of
174 sqlerrd and sqlwarn currently contain no useful information.
176 The structure sqlca is not defined in the SQL standard, but is
177 implemented in several other SQL database systems. The definitions are
178 similar at the core, but if you want to write portable applications,
179 then you should investigate the different implementations carefully.
181 Here is one example that combines the use of WHENEVER and sqlca,
182 printing out the contents of sqlca when an error occurs. This is
183 perhaps useful for debugging or prototyping applications, before
184 installing a more “user-friendly” error handler.
185 EXEC SQL WHENEVER SQLERROR CALL print_sqlca();
190 fprintf(stderr, "==== sqlca ====\n");
191 fprintf(stderr, "sqlcode: %ld\n", sqlca.sqlcode);
192 fprintf(stderr, "sqlerrm.sqlerrml: %d\n", sqlca.sqlerrm.sqlerrml);
193 fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);
194 fprintf(stderr, "sqlerrd: %ld %ld %ld %ld %ld %ld\n", sqlca.sqlerrd[0],sqlca
195 .sqlerrd[1],sqlca.sqlerrd[2],
196 sqlca.sqlerrd[3],sqlca
197 .sqlerrd[4],sqlca.sqlerrd[5]);
198 fprintf(stderr, "sqlwarn: %d %d %d %d %d %d %d %d\n", sqlca.sqlwarn[0], sqlc
199 a.sqlwarn[1], sqlca.sqlwarn[2],
200 sqlca.sqlwarn[3], sqlc
201 a.sqlwarn[4], sqlca.sqlwarn[5],
202 sqlca.sqlwarn[6], sqlc
204 fprintf(stderr, "sqlstate: %5s\n", sqlca.sqlstate);
205 fprintf(stderr, "===============\n");
208 The result could look as follows (here an error due to a misspelled
213 sqlerrm.sqlerrmc: relation "pg_databasep" does not exist on line 38
215 sqlwarn: 0 0 0 0 0 0 0 0
219 34.8.3. SQLSTATE vs. SQLCODE #
221 The fields sqlca.sqlstate and sqlca.sqlcode are two different schemes
222 that provide error codes. Both are derived from the SQL standard, but
223 SQLCODE has been marked deprecated in the SQL-92 edition of the
224 standard and has been dropped in later editions. Therefore, new
225 applications are strongly encouraged to use SQLSTATE.
227 SQLSTATE is a five-character array. The five characters contain digits
228 or upper-case letters that represent codes of various error and warning
229 conditions. SQLSTATE has a hierarchical scheme: the first two
230 characters indicate the general class of the condition, the last three
231 characters indicate a subclass of the general condition. A successful
232 state is indicated by the code 00000. The SQLSTATE codes are for the
233 most part defined in the SQL standard. The PostgreSQL server natively
234 supports SQLSTATE error codes; therefore a high degree of consistency
235 can be achieved by using this error code scheme throughout all
236 applications. For further information see Appendix A.
238 SQLCODE, the deprecated error code scheme, is a simple integer. A value
239 of 0 indicates success, a positive value indicates success with
240 additional information, a negative value indicates an error. The SQL
241 standard only defines the positive value +100, which indicates that the
242 last command returned or affected zero rows, and no specific negative
243 values. Therefore, this scheme can only achieve poor portability and
244 does not have a hierarchical code assignment. Historically, the
245 embedded SQL processor for PostgreSQL has assigned some specific
246 SQLCODE values for its use, which are listed below with their numeric
247 value and their symbolic name. Remember that these are not portable to
248 other SQL implementations. To simplify the porting of applications to
249 the SQLSTATE scheme, the corresponding SQLSTATE is also listed. There
250 is, however, no one-to-one or one-to-many mapping between the two
251 schemes (indeed it is many-to-many), so you should consult the global
252 SQLSTATE listing in Appendix A in each case.
254 These are the assigned SQLCODE values:
257 Indicates no error. (SQLSTATE 00000)
259 100 (ECPG_NOT_FOUND) #
260 This is a harmless condition indicating that the last command
261 retrieved or processed zero rows, or that you are at the end of
262 the cursor. (SQLSTATE 02000)
264 When processing a cursor in a loop, you could use this code as a
265 way to detect when to abort the loop, like this:
270 if (sqlca.sqlcode == ECPG_NOT_FOUND)
274 But WHENEVER NOT FOUND DO BREAK effectively does this
275 internally, so there is usually no advantage in writing this out
278 -12 (ECPG_OUT_OF_MEMORY) #
279 Indicates that your virtual memory is exhausted. The numeric
280 value is defined as -ENOMEM. (SQLSTATE YE001)
282 -200 (ECPG_UNSUPPORTED) #
283 Indicates the preprocessor has generated something that the
284 library does not know about. Perhaps you are running
285 incompatible versions of the preprocessor and the library.
288 -201 (ECPG_TOO_MANY_ARGUMENTS) #
289 This means that the command specified more host variables than
290 the command expected. (SQLSTATE 07001 or 07002)
292 -202 (ECPG_TOO_FEW_ARGUMENTS) #
293 This means that the command specified fewer host variables than
294 the command expected. (SQLSTATE 07001 or 07002)
296 -203 (ECPG_TOO_MANY_MATCHES) #
297 This means a query has returned multiple rows but the statement
298 was only prepared to store one result row (for example, because
299 the specified variables are not arrays). (SQLSTATE 21000)
301 -204 (ECPG_INT_FORMAT) #
302 The host variable is of type int and the datum in the database
303 is of a different type and contains a value that cannot be
304 interpreted as an int. The library uses strtol() for this
305 conversion. (SQLSTATE 42804)
307 -205 (ECPG_UINT_FORMAT) #
308 The host variable is of type unsigned int and the datum in the
309 database is of a different type and contains a value that cannot
310 be interpreted as an unsigned int. The library uses strtoul()
311 for this conversion. (SQLSTATE 42804)
313 -206 (ECPG_FLOAT_FORMAT) #
314 The host variable is of type float and the datum in the database
315 is of another type and contains a value that cannot be
316 interpreted as a float. The library uses strtod() for this
317 conversion. (SQLSTATE 42804)
319 -207 (ECPG_NUMERIC_FORMAT) #
320 The host variable is of type numeric and the datum in the
321 database is of another type and contains a value that cannot be
322 interpreted as a numeric value. (SQLSTATE 42804)
324 -208 (ECPG_INTERVAL_FORMAT) #
325 The host variable is of type interval and the datum in the
326 database is of another type and contains a value that cannot be
327 interpreted as an interval value. (SQLSTATE 42804)
329 -209 (ECPG_DATE_FORMAT) #
330 The host variable is of type date and the datum in the database
331 is of another type and contains a value that cannot be
332 interpreted as a date value. (SQLSTATE 42804)
334 -210 (ECPG_TIMESTAMP_FORMAT) #
335 The host variable is of type timestamp and the datum in the
336 database is of another type and contains a value that cannot be
337 interpreted as a timestamp value. (SQLSTATE 42804)
339 -211 (ECPG_CONVERT_BOOL) #
340 This means the host variable is of type bool and the datum in
341 the database is neither 't' nor 'f'. (SQLSTATE 42804)
344 The statement sent to the PostgreSQL server was empty. (This
345 cannot normally happen in an embedded SQL program, so it might
346 point to an internal error.) (SQLSTATE YE002)
348 -213 (ECPG_MISSING_INDICATOR) #
349 A null value was returned and no null indicator variable was
350 supplied. (SQLSTATE 22002)
352 -214 (ECPG_NO_ARRAY) #
353 An ordinary variable was used in a place that requires an array.
356 -215 (ECPG_DATA_NOT_ARRAY) #
357 The database returned an ordinary variable in a place that
358 requires array value. (SQLSTATE 42804)
360 -216 (ECPG_ARRAY_INSERT) #
361 The value could not be inserted into the array. (SQLSTATE 42804)
363 -220 (ECPG_NO_CONN) #
364 The program tried to access a connection that does not exist.
367 -221 (ECPG_NOT_CONN) #
368 The program tried to access a connection that does exist but is
369 not open. (This is an internal error.) (SQLSTATE YE002)
371 -230 (ECPG_INVALID_STMT) #
372 The statement you are trying to use has not been prepared.
375 -239 (ECPG_INFORMIX_DUPLICATE_KEY) #
376 Duplicate key error, violation of unique constraint (Informix
377 compatibility mode). (SQLSTATE 23505)
379 -240 (ECPG_UNKNOWN_DESCRIPTOR) #
380 The descriptor specified was not found. The statement you are
381 trying to use has not been prepared. (SQLSTATE 33000)
383 -241 (ECPG_INVALID_DESCRIPTOR_INDEX) #
384 The descriptor index specified was out of range. (SQLSTATE
387 -242 (ECPG_UNKNOWN_DESCRIPTOR_ITEM) #
388 An invalid descriptor item was requested. (This is an internal
389 error.) (SQLSTATE YE002)
391 -243 (ECPG_VAR_NOT_NUMERIC) #
392 During the execution of a dynamic statement, the database
393 returned a numeric value and the host variable was not numeric.
396 -244 (ECPG_VAR_NOT_CHAR) #
397 During the execution of a dynamic statement, the database
398 returned a non-numeric value and the host variable was numeric.
401 -284 (ECPG_INFORMIX_SUBSELECT_NOT_ONE) #
402 A result of the subquery is not single row (Informix
403 compatibility mode). (SQLSTATE 21000)
406 Some error caused by the PostgreSQL server. The message contains
407 the error message from the PostgreSQL server.
410 The PostgreSQL server signaled that we cannot start, commit, or
411 rollback the transaction. (SQLSTATE 08007)
413 -402 (ECPG_CONNECT) #
414 The connection attempt to the database did not succeed.
417 -403 (ECPG_DUPLICATE_KEY) #
418 Duplicate key error, violation of unique constraint. (SQLSTATE
421 -404 (ECPG_SUBSELECT_NOT_ONE) #
422 A result for the subquery is not single row. (SQLSTATE 21000)
424 -602 (ECPG_WARNING_UNKNOWN_PORTAL) #
425 An invalid cursor name was specified. (SQLSTATE 34000)
427 -603 (ECPG_WARNING_IN_TRANSACTION) #
428 Transaction is in progress. (SQLSTATE 25001)
430 -604 (ECPG_WARNING_NO_TRANSACTION) #
431 There is no active (in-progress) transaction. (SQLSTATE 25P01)
433 -605 (ECPG_WARNING_PORTAL_EXISTS) #
434 An existing cursor name was specified. (SQLSTATE 42P03)