Previous | Table of Contents | Next |
Step 3: Fetch and Process
Here is where all the work occurs. The following code fetches a row into local variables. You may also fetch the columns directly, which will print them to the screen just as a normal SELECT would. In this example, I use the PRINT statement to send results to the screen. Because Im using PRINT, I dont have column headers provided automatically for me. Many cursor programs are used for server processing only, and do not return rows in this fashion. As you can see, its a lot less convenient than a simple SELECT.
set nocount on declare @type char(12), @price money, @title varchar(80), @tempstr varchar(40) print Title Price print ---------------------- ---------- fetch next from titles_curs into @title, @type, @price while @@fetch_status = 0 begin if @type = business select @price = @price * 1.25 if @price is null select @tempstr = convert(char(22), @title) + --No pricing-- else select @tempstr = convert(char(22), @title) + convert(char(7), @price) print @tempstr fetch next from titles_curs into @title, @type, @price end
Title Price ------------------ ---------- The Psychology of Comp --No pricing-- Cooking with Computers 14.94 Straight Talk About Co 24.99 The Busy Executives D 24.99 You Can Combat Compute 3.74 Silicon Valley Gastron 19.99 The Gourmet Microwave 2.99 But Is It User Friendl 22.95 Net Etiquette --No pricing-- Secrets of Silicon Val 20.00 Computer Phobic AND No 21.59 Emotional Security: A 7.99 Is Anger the Enemy? 10.95 Life Without Fear 7.00 Prolonged Data Depriva 19.99 Fifty Years in Bucking 11.95 Onions, Leeks, and Gar 20.95 Sushi, Anyone? 14.99
I set nocount on to eliminate the n rows affected messages. Otherwise, every time a fetch was performed, I would have gotten a message. This would have made the output rather unappealing.
At the beginning of the procedure, I declared some variables to hold fetched values. These variables must be of the same type as the columns that are being fetched. There is no implicit conversion during fetch, so if you try to fetch a money column into an integer data type, you will receive a conversion error.
After declaring local work variables, I print the column headers. This is just a couple of simple PRINT statements. If you were processing this inside an application program, the prints wouldnt be returned as normal results. Instead, they would go through the applications message handler.
The first fetch occurs on line six. This gets the first row in the cursor keyset.
A cursor keyset refers to the set of rows that are part of this cursors scope. For sensitive cursors (also called dynamic cursors), if a row is deleted from the keyset, the row remains in the set, but will return null values for all columns if fetched.
It also seeds the @@fetch_status variable. The @@fetch_status variable will always have one of three values. If the most recent fetch succeeded, the @@fetch_status will be 0. If the most recent fetch failed because there are no more rows to fetch (or in the case of moving too far ahead or too far backward, the fetch landed outside the current keyset), @@fetch_status will be 1. If the row no longer exists (you are using a sensitive cursor and the underlying row was deleted), the @@fetch_status will be 2, and all row values will be null.
The loop that I have set up will fetch rows until a 1 is returned. If there is a problem where a row gets deleted in the middle of the set (and @@fetch_status is 2), that will abort the loop, too.
Inside the loop, the value of @type is tested. If the current row is a business book, I increase the price by 25 percent. Then, the value of @price is tested. If the price is null, print a custom message rather than null. Finally, the messages are all gathered together in a temporary work string and printed to the console. The next row is fetched, and the loop begins again.
Close the Cursor
After the cursor has fetched itself out, close the cursor.
close titles_curs
Closing the cursor destroys the cursor keys et. Put another way, closing the cursor wipes out the result set on which the cursor is operating. The cursor declaration is still active, however, and may bereopened with an OPEN statement after it has been closed. You may want to do this if you are using an insensitive cursor and want to refresh the result set.
Deallocating the Cursor
Deallocation frees the memory on the server that has been set aside for the cursor. Deallocation is the final cleanup step.
deallocate titles_curs
If you do not deallocate the cursor, memory will remain tied up until your connection is closed. If you have declared a cursor, you may not declare another with the same name until you have deallocated the old one.
Previous | Table of Contents | Next |