INF: How to Process Results in an ESQL ApplicationLast reviewed: March 26, 1997Article ID: Q151599 |
The information in this article applies to:
SUMMARYWhen you process results from an ESQL application, always take into account that ESQL only processes a single result set. This is most likely to become an issue when you execute a stored procedure via the EXECUTE IMMEDIATE statement or use a CURSOR implementation. For example: Create procedure spTest as select au_lname from authors select au_fname from authorsgo In a DB-Library application, this stored procedure is treated and retrieved as two result sets: au_lname and au_fname. The DB-Library application calls dbresults multiple times in conjunction with dbcmdrow to determine the result set information. By design, ESQL is platform independent, allowing you to use the samesource code and another precompiler to access a different DBMS environment. To accomplish this, ESQL handles each statement as a single result set. If you execute the spTest stored procedure, it really produces two result sets from SQL Server, but the ESQL application will only see the first result set. The following code sample contains examples of executing a stored procedure: EXEC SQL BEGIN DECLARE SECTION; char strTest[15] = "spTest"; char strName[51] = "";EXEC SQL END DECLARE SECTION;
// // Install the error handlers //EXEC SQL WHENEVER SQLERROR CALL ErrorHandler(); EXEC SQL WHENEVER SQLWARNING CALL ErrorHandler(); EXEC SQL WHENEVER NOT FOUND CALL ErrorHandler(); . . .
// // Using a cursor //EXEC SQL DECLARE C_2 CURSOR FOR STMT1; EXEC SQL PREPARE STMT1 FROM :strTest; EXEC SQL OPEN C_2; while(SQLCODE == 0) { EXEC SQL FETCH C_2 INTO :strName; . . . // // Using EXECUTE IMMEDIATE //EXEC SQL EXECUTE IMMEDIATE :strTest; . . . Depending on how you attempt to process the results, you may get different SQLCODE settings. When you are processing the results as a cursor, the OPEN returns (0) and the FETCH will continue to return (0) until it reaches the end of the first result set, and then it returns (100) as expected. The EXECUTE IMMEDIATE returns a SQLCODE of (1). As documented, EXECUTE IMMEDIATE cannot return result rows. We can complicate the issue a bit by adding a RAISERROR command to the stored procedure. Create procedure spTest as RAISERROR(50001, 1, 1) select au_lname from authorsgo The RAISERROR statement will be treated as the result set that does not return any result rows. In the case of the OPEN, the SQLCODE is set to -50001, and in the EXECUTE IMMEDIATE, the SQLCODE is set to -50001. The RAISERROR is considered to be the result set and you cannot access the result rows returned from the select. Reversing the stored procedure changes the behavior: Create procedure spTest as select au_lname from authors RAISERROR(50001, 1, 1)go You again get the select result set but you do not see the RAISERROR of -50001 from the OPEN. However, the EXECUTE IMMEDIATE sets the SQLCODE to 1 because result rows were returned. In all of the above examples, you can change the behavior by not returning results, meaning that if you take the third variation of the stored procedure and add a where clause--such as "where au_lname = '12'"--the computer no longer returns result rows but an empty result set. In this case, the SQLCODE is set to -50001 for both the OPEN and the EXECUTE IMMEDIATE statements, because the first result set did not return rows. Finally, if you attempt to ignore the SQLCODE, you get unpredictable results. If you do a RAISERROR and then a select, you can modify the cursor code. While((SQLCODE == 0) || (SQLCODE == -50001)) { EXEC SQL FETCH C_2 INTO :strName; . . .This specific case allows you to process the results from the select statement. This is not a recommended or supported method of ESQL result set processing. You should always guarantee that only one result set can be returned from any given statement.
|
Additional reference words: 4.22 esqlc 6.00
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |