| United States-English |
|
|
|
![]() |
ALLBASE/SQL FORTRAN Application Programming Guide: HP 9000 Computer Systems > Chapter 5 Runtime Status Checking and the SQLCAApproaches to Status Checking |
|
You can use one or both of the following approaches to checking SQLCA values:
Error and warning conditions detected by either type of status checking can be conveyed to the program user in several ways:
This section illustrates various ways to use explicit and implicit status checking and notify program users of the results of status checking. The WHENEVER command syntax consists of two components: a condition and an action:
There are three conditions:
A WHENEVER command for each of these conditions can be in effect at the same time. There are also three actions:
Any of these three actions may be specified for any of these three conditions. The WHENEVER command causes the FORTRAN preprocessor to generate status-checking and status-handling code for each SQL command that comes after it sequentially in the program. In the following program sequence, for example, the WHENEVER command in SubprogramUnit1 is in effect for SQLCOMMAND1, but not for SQLCOMMAND2, even though SQLCOMMAND1 is executed first at runtime:
The code generated reflects the condition and action in a WHENEVER command. In the example above, the preprocessor inserts both a test for a negative value in SQLCode, an SQLCode value equal to 100, and an SQLWarn(0) value equal to W, and a statement that invokes the error handling code routines located at Labels 2000, 3000, and 4000 respectfully, as shown in the following example.
As this example illustrates, you can pass control with a WHENEVER command to an exception-handling code routine within the same program unit where the error condition occurred. Because you use a GOTO statement rather than a CALL statement, after the exception-handling subprogram unit is executed, control cannot automatically return to the statement which caused the error to occur. You must use another GOTO or a CALL statement to explicitly pass control to a specific point in your program:
This exception-handling subprogram unit explicitly checks the first SQLCode returned. The program terminates or it continues from the Restart/Reentry point after all warning and error messages are displayed. Note that a CALL statement had to be used in this code routine in order to allow the program to transfer control to a specific point. A GOTO statement transfers control only to another point in the same subprogram unit and a RETURN statement returns control to the point in the program where the error handling subprogram unit was called. Using a CALL statement may be impractical when you want execution to continue from different places in the program, depending on the part of the program that provoked the error. How to handle this case is discussed under "Explicit Status Checking" later in this chapter. The FORTRAN preprocessor generates status-checking and status-handling code for each SQL command that comes after a WHENEVER statement in the source code until another WHENEVER statement is found. If the WHENEVER statement includes a GOTO, there must be a corresponding label in each subsequent subprogram unit following the WHENEVER statement that includes SQL commands, or until another WHENEVER statement is encountered. It is recommended that a WHENEVER condition CONTINUE statement be included at the end of each subprogram unit that contains a WHENEVER condition GOTO statement to eliminate the possibility of having an unresolved external error at compile time. The program illustrated in Figure 5-1 contains five WHENEVER commands:
The code routine located at Label 1000 is executed when an error occurs during the processing of session-related and transaction-related commands. The program terminates after displaying all available error messages. If a warning condition occurs during the execution of these commands, the warning condition is ignored, because the WHENEVER SQLWARNING CONTINUE command is in effect by default. The code routine located at Label 2000 is executed when an error occurs during the processing of the SELECT command. This code routine explicitly examines the SQLCode value to determine whether it is -10002, in which case it displays a warning message. If SQLCode contains another value, subprogram unit SQLStatusCheck is executed. SQLStatusCheck explicitly examines SQLCode to determine whether a deadlock or shared memory problem occurred (SQLCode = -14024 or -4008 respectively) or whether the error was serious enough to warrant terminating the program (SQLCode < -14024).
The code routine located at Label 3000 is executed when only a warning condition results during execution of the SELECT command. This code routine displays a message and the row of data retrieved, commits work, and then prompts the user for another PartNumber. The NOT FOUND condition that may be associated with the SELECT command is handled by the code routine located at Label 4000. This code routine displays the message, Row not found!, then passes control to subprogram unit EndTransaction. SQLEXPLAIN does not provide a message for the NOT FOUND condition, so the program must provide one itself. Figure 5-1 Program forex5: Implicit and Explicit Status Checking
The example examined under "Implicit Status Checking" has already illustrated several uses for explicit status checking:
SQLCA values are explicitly examined in this example in order to:
This section examines when you may want to invoke such status-checking code routines explicitly rather than implicitly. In addition, this section illustrates how SQLErrd(3) and several SQLCode values can be explicitly used to monitor the number of rows operated on by data manipulation commands. The example in Figure 5-1 illustrates how status-checking code can be consolidated within individual subprogram units. This approach can sometimes reduce the amount of status-checking code. As the number of SQL operations in a program increases, however, the likelihood of needing to return to different places in the program after execution of such a subprogram unit increases. In this case, you invoke the subprogram units after explicitly checking SQLCA values rather than using the WHENEVER command to implicitly check these values. The example shown in Figure 5-2 contains four data manipulation operations: INSERT, UPDATE, DELETE, and SELECT. Each of these operations is executed from its own subprogram unit. As in the program in Figure 5-1, one subprogram unit is used for explicit error handling: SQLStatusCheck. Unlike the program in Figure 5-2; however, this subprogram unit is invoked after explicit test of SQLCode is made, immediately following each data manipulation operation. In the program in Figure 5-2, tests for warning conditions are omitted. Because error handling is performed in a subprogram unit rather than in a code routine following the embedded SQL command, control returns to the point in the program where SQLStatusCheck is invoked. Figure 5-2 Explicitly Invoking Status-Checking Subprogram Units
SQLErrd(3) is useful in determining how many rows were processed in one of the following operations when the operation could be executed without error:
The SQLErrd(3) value can be used in these cases only when SQLCode does not contain a negative number. When SQLCode is 0, SQLErrd(3) is always equal to 1 for SELECT, FETCH, UPDATE WHERE CURRENT, and DELETE WHERE CURRENT operations. SQLErrd(3) may be greater than 1 if more than one row qualifies for an INSERT, UPDATE, or DELETE operation. When SQLCode is 100, SQLCA.SQLErrd(3) is 0. The remainder of this chapter examines techniques for explicitly checking SQLErrd(3) as well as using SQLCodes of 100 and -10002 in data manipulation logic. The example in Figure 5-2 could be modified to display the number of rows updated or deleted by using SQLErrd(3). In the case of the update operation, for example, the actual number of rows updated could be displayed after the UPDATE command is executed.
If the UPDATE command is successfully executed, SQLCode equals zero and SQLErrd(3) contains the number of rows updated. If the UPDATE command cannot be successfully executed, SQLCode contains a negative number and SQLErrd(3) contains a zero. In the case of the delete operation, the actual number of rows deleted could be displayed after the DELETE command is executed.
If the DELETE command is successfully executed, SQLCode equals 0 and SQLErrd(3) contains the number of rows deleted. If the DELETE command cannot be successfully executed, SQLCode contains a negative number and SQLErrd(3) contains a 0. The programs already examined in this chapter have illustrated how an SQLCode of 100 can be detected and handled for data manipulation commands that do not use a cursor. When a cursor is being used, this SQLCode value is used to determine when all rows in an active set have been fetched:
In this example, the active set is defined when the OPEN command is executed. The cursor is then positioned before the first row of the active set. When the FETCH command is executed, the first row in the active set is placed into the program's host variables, then displayed. The FETCH command retrieves one row at a time into the host variables until the last row in the active set has been retrieved; after the last row has been fetched from the active set the next attempt to FETCH sets SQLCode to a value of 100. If no rows qualify for the active set, SQLCode equals 100 the first time subprogram unit FetchRow is executed. If more than one row qualifies for a SELECT or FETCH operation, ALLBASE/SQL sets SQLCode to -10002. The program in Figure 5-3 contains an explicit test for this value. When SQLCode is equal to MultipleRows (defined as -10002 in the Type Declaration Section), a status checking subprogram unit is not invoked, but a warning message is displayed:
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||