Don't be too quick to use a cursor

Who is online?  0 guests and 0 members
Home  »  Articles  »  Don't be too quick to use a cursor

Don't be too quick to use a cursor

change text size: A A A
Published: 12/22/2009 by  jtarnott  - Views:  [503]  

In an article posted here by Dustin Ryan, http://www.bidn.com/articles/integration-services/46/using-a-t-sql-cursor, you can learn the basics of using a cursor in Transact-SQL.  It never hurts to understand all the tools available, so this explanation of how a cursor can be coded does have value. I would object, though, to the implication that cursors should be expected to be necessary very often at all. The example Dustin gives of retrieving the Identity column of an inserted row for use in subsequent correlations or logging may well have been effected with the use of the OUTPUT clause in the original insert. There may have been, no, there probably were other complications that led him to use the cursor, but for a simple case of just knowing the value, the following code may be a model for an alternative set-based approach.

-- Create two tables to play with
create table Table_1 (ID int identity,
				Field_1 varchar(255) null)
create table Table_2 (ID int identity,
				Field_1 varchar(255) null)
-- Insert four rows in first table 
Insert table_1 (Field_1) values('Something from table 1')
Insert table_1 (Field_1) values('Something else from table 1')
Insert table_1 (Field_1) values('Something more from table 1')
Insert table_1 (Field_1) values('One more thing from table 1')
-- Insert four rows in second table 
Insert table_2 (Field_1) values('Something from table 2')
Insert table_2 (Field_1) values('Something else from table 2')
Insert table_2 (Field_1) values('Something more from table 2')
Insert table_2 (Field_1) values('One more thing from table 2')
-- Look at the contents
select * from table_1
select * from table_2
-- Declare a table variable to hold selected fields of the inserted data.
Declare @Inserted table(ID int) 
--Insert with OUTPUT clause to capture all inserted IDs
Insert table_1
   Output Inserted.ID   -- More fields may have been captured: , Inserted.Field_2 
     into @Inserted
   Select Field_1 from Table_2 t2 --What gets inserted to table_1 is from Table_2
 where t2.ID %2 = 0               --Where the ID is an even number (2 and 4 in this case0
-- Look at data in both tables and the table variable based on the newly inserted IDs
select	 i.id as Inserted_ID
		,t1.id as Table_1_ID
		,t1.Field_1 as Table_1_Fld_1
		,t2.id as Table_2_ID
		,t2.Field_1 as Table_2_Fld_1
  from @Inserted i
  join table_1 t1 on t1.id = i.ID
  join table_2 t2 on t2.Field_1 = t1.Field_1
-- Drop the tables
Drop table Table_1 Drop table Table_2

This approach let's the SQL Server optimizer develop a much more efficiency plan for the database activity than would be created with the explicit row by row processing of a cursor. The key points to understanding this are first that the OUTPUT clause can capture named fields from an Insert or Delete statement and that this then allows us to queue up such data in a table (or as in this example, a table variable) for further processing.

 

 
0
/5
Avg: 0/5: (0 votes)

Comments (1)

dustinryan
dustinryan said:
Very informative. Well done and thanks for the plug! :)
12/22/2009
 · 
 
by

Most Recent Articles