Install a user function to handle server messages.
int (*dbmsghandle(handler))() int (*handler)();
A pointer to the user function that will be called whenever DB-Library receives an error or informational message from the server. DB-Library calls this function with eight parameters listed in Table 2-21.
Parameter |
Meaning |
---|---|
dbproc |
The affected DBPROCESS. |
msgno |
The current message’s number (datatype DBINT). These numbers are documented in the sysmessages table. |
msgstate |
The current message’s error state number (datatype int). These numbers provide Sybase Technical Support with information about the context of the error. |
severity |
The current message’s information class or error severity (datatype int). These numbers are documented in the Adaptive Server Enterprise documentation. |
msgtext |
The null-terminated text of the current message (datatype char *). |
srvname |
The null-terminated name of the server that generated the message (datatype char *). A server’s name is stored in the srvname column of its sysservers system table. It is used in server-to-server communication; in particular, it is used when one server logs into another server to perform a remote procedure call. If the server has no name, srvname will be a length of 0. |
procname |
The null-terminated name of the stored procedure that generated the message (datatype char *). If the message was not generated by a stored procedure, procname will be a length of 0. |
line |
The number of the command batch or stored procedure line that generated the message (datatype int). Line numbers start at 1. The line number pertains to the nesting level at which the message was generated. For instance, if a command batch executes stored procedure A, which then calls stored procedure B, and a message is generated at line 3 of B, then the value of line is 3. line will be 0 if there is no line number associated with the message. Circumstances that could generate messages without line numbers include a login error or a remote procedure call (performed using dbrpcsend) to a stored procedure that does not exist. |
The message handler must return a value of 0 to DB-Library.
Message handlers on Windows must be declared with CS_PUBLIC, as shown in the following example. For portability, callback handlers on other platforms should be declared CS_PUBLIC as well.
The following example shows a typical message handler routine:
#include <sybfront.h>
#include <sybdb.h>
int CS_PUBLIC msg_handler(dbproc, msgno, msgstate,
severity, msgtext, srvname, procname, line)
DBPROCESS *dbproc;
DBINT msgno;
int msgstate;
int severity;
char *msgtext;
char *srvname;
char *procname;
int line;
{
printf ("Msg %ld, Level %d, State %d\n",
msgno, severity, msgstate);
if (strlen(srvname) > 0)
printf ("Server ’%s’, ", srvname);
if (strlen(procname) > 0)
printf ("Procedure ’%s’, ", procname);
if (line > 0)
printf ("Line %d", line);
printf("\n\t%s\n", msgtext);
return(0);
}
A pointer to the previously installed message handler or NULL if no message handler was installed before.
dbmsghandle installs a message-handler function that you supply. When DB-Library receives a server error or informational message, it will call this message handler immediately. You must install a message handler to handle server messages properly.
If an application does not call dbmsghandle to install a message-handler function, DB-Library ignores server messages. The messages are not printed.
If the command buffer contains just a single command and that command provokes a server message, DB-Library will call the message handler during dbsqlexec.If the command buffer contains multiple commands (and the first command in the buffer is ok), a runtime error will not cause dbsqlexec to fail. Instead, failure will occur with the dbresults call that processes the command causing the runtime error.
You can “de-install” an existing message handler by calling dbmsghandle with a NULL parameter. You can also, at any time, install a new message handler. The new handler will automatically replace any existing handler.
Refer to the sysmessages table for a list of server messages. In addition, the Transact-SQL print and raiserror commands generate server messages that dbmsghandle will catch.
The routines dbsetuserdata and dbgetuserdata can be particularly useful when you need to transfer information between the message handler and the program code that triggered it. See the dbsetuserdata reference page for an example of how to handle deadlock in this way.
Another routine, dberrhandle, installs an error handler that DB-Library calls in response to DB-Library errors.
If the application provokes messages from DB-Library and the server simultaneously, DB-Library calls the server message handler before it calls the DB-Library error handler.
The DB-Library/C error value SYBESMSG is generated in response to a server error message, but not in response to a server informational message. This means that when a server error occurs, both the server message handler and the DB-Library/C error handler are called, but when the server generates an informational message, only the server message handler is called.
If you have installed a server message handler, you may want to write your DB-Library error handler so as to suppress the printing of any SYBESMSG error, to avoid notifying the user about the same error twice.
Table 2-22 provides information on when DB-Library/C calls an application’s message and error handlers.
Error or message |
Message handler called? |
Error handler called? |
---|---|---|
SQL syntax error |
Yes |
Yes (SYBESMSG). (Code the handler to ignore the message.) |
SQL print statement |
Yes |
No. |
SQL raiserror |
Yes |
No. |
Server dies |
No |
Yes (SYBESEOF). (Code your handler to exit the application.) |
Timeout from the server |
No |
Yes (SYBETIME). (To wait for another timeout period, code your handler to return -INT_CONTINUE.) |
Deadlock on query |
Yes |
No. (Code your handler to test for deadlock.) |
Timeout on login |
No |
Yes (SYBEFCON). |
Login fails (dbopen) |
Yes |
Yes (SYBEPWD). (Code your handler to exit the application.) |
Use database message |
Yes (Code the handler to ignore the message.) |
No. |
Incorrect use of DB-Library/C calls, such as not calling dbresults when required |
No |
Yes (SYBERPND). |
Fatal Server error (severity greater than 16) |
Yes |
Yes (SYBESMSG). |