"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" GET MORE OUT OF A SINGLE DECLARE CURSOR COMMAND """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" PRODUCT : R:BASE VERSION : 3.1 CATEGORY : PROGRAMMING SUBCATEGORY : TOOLS """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" From Bill Downall, 5411 White Willow Court, Indianapolis, IN 46254- 9633. Bill is a database consultant and educator. You can reach him at 317-297-3810 or through David M. Blocker and Associates at 617-784- 1919. The DECLARE CURSOR command has the full power of the SELECT command embedded in it, so you can do many jobs at once. You may be able to speed up WHILE loops and reduce the need for time-consuming memory swaps by reducing the number of different commands you use. For example, you can improve the performance of some cursor processing loops by using the SELECT clause in the DECLARE CURSOR to replace lookups that use SET VAR processing. The example below shows you how to optimize a DECLARE CURSOR structure by folding other commands into the DECLARE CURSOR itself. Original DECLARE CURSOR """"""""""""""""""""""" The following block of code uses these four commands: DECLARE CURSOR, FETCH, SET VAR, and SELECT: DECLARE c1 CURSOR AS SELECT + idnum, + fn, + mi, + ln, + zipcode + FROM people + ORDER BY ln, fn, mi OPEN c1 FETCH c1 INTO + vidnum, + vfn, + vmi IND nomi, + vln, + vzip IND nozip WHILE SQLCODE <> 100 THEN *( Build a full name from the pieces.) SET VAR vfullname = (.vfn & .vmi & .vln) *( Look up city & state for this zip.) SELECT city, state INTO + vcity IND nocity, + vstate IND nostate + FROM cszs + WHERE zipcode = (.vzip) *( ...many other commands here...) FETCH c1 INTO vidnum, vfn, + vmi IND nomi, vln, vzip IND nozip ENDWHILE DROP CURSOR c1 Optimized DECLARE CURSOR """""""""""""""""""""""" By folding the SET VAR and SELECT commands into the original DECLARE CURSOR, you can accomplish the same thing using only DECLARE CURSOR and FETCH: DECLARE c1 CURSOR AS SELECT + p1.idnum, + (p1.fn & p1.mi & p1.ln), + p1.zipcode, + z1.city, + z1.state + FROM people p1, cszs z1 + WHERE p1.zipcode = z1.zipcode + ORDER BY p1.ln, p1.fn, p1.mi OPEN c1 FETCH c1 INTO + vidnum, + vfullname, + vzip, + vcity IND nocity, + vstate IND nostate WHILE SQLCODE <> 100 THEN *( ...many other commands go here...) FETCH c1 INTO + vidnum, + vfullname, + vzip, + vcity IND nocity, + vstate IND nostate ENDWHILE DROP CURSOR c1 In this optimized DECLARE CURSOR structure, the SELECT clause joins the two tables (PEOPLE and CSZS) together. The WHERE clause (WHERE p1.zipcode = z1.zipcode) automatically ensures that only rows with existing zip codes are included, so you no longer need an INDICATOR variable for VZIP. SQL automatically rejects the null values when performing the join. Make sure the column ZIPCODE is an indexed column. SQL uses indexes to speed up joins. The SELECT clause can select data from multiple tables, group rows, calculate expressions, append rows together, and load variables with values. By using the full power of the SELECT clause in DECLARE CURSOR, INSERT, CREATE VIEW, and SELECT commands, you may be able to reduce code and increase speed.