Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 SQL Server Administration (2000)
 Cursors or Direct T-SQL

Author  Topic 

Shastryv
Posting Yak Master

145 Posts

Posted - 2004-09-10 : 14:22:26
I need to run an update on table that affects around 7000 rows. I want to write a straight UPDATE statement which includes a IN clause with Sub query returns multiple values
But this guy wants to implement in a CURSOR reading row by row and update each row. I know for sure its going to take longer time than a straight update. Do you guys see any benefit using cursor in this case??? Which one you prefer??
I only use cursor If have to

Thanks
Shas3

ehorn
Master Smack Fu Yak Hacker

1632 Posts

Posted - 2004-09-10 : 14:23:51
My experience suggests there is never a benefit in using a cursor...
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2004-09-10 : 14:43:50
(not even readnig qestfion typing with my eeys closed )

T_SQL !!



- Jeff
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2004-09-10 : 15:27:39
You can type with your eyes closed...see he's not even reading this...



Brett

8-)
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2004-09-10 : 15:30:38
quote:
Originally posted by Shastryv

But this guy wants to implement in a CURSOR reading row by row and update each row.




IF @GuyIsBoss
EXEC WriteCursor
ELSE
EXEC DoItTheRightWay


Show us the Table DDL and what you have to do.....

Ask him if he'd prefer an nested curosr...place all of the values of an in clause...wait I have to write this one...



Brett

8-)
Go to Top of Page

ehorn
Master Smack Fu Yak Hacker

1632 Posts

Posted - 2004-09-10 : 15:56:27
quote:
Ask him if he'd prefer an nested curosr...place all of the values of an in clause...wait I have to write this one...
Why not use a little dynamic SQL on that nested cursor...

Go to Top of Page

nr
SQLTeam MVY

12543 Posts

Posted - 2004-09-10 : 16:02:35
Don't even need to type anything.

The cursor might not be slower but it will restrict the changes you can make in the future.
7000 rows is tiny so performance shouldn't be a problem unless you do it many times a minute.


==========================================
Cursors are useful if you don't know sql.
DTS can be used in a similar way.
Beer is not cold and it isn't fizzy.
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2004-09-10 : 16:08:29
quote:
Originally posted by nr

The cursor might not be slower...



Ok we've seen that...but what percentage of the time..less than 1?

quote:
but it will restrict the changes you can make in the future.


Ok, what does that mean?

PS

Notice the sig

quote:

==========================================
Cursors are useful if you don't know sql.
DTS can be used in a similar way.
Beer is not cold and it isn't fizzy.



Also, they only time (besides the 1%) is when 1). You have to call a system function and pass values to it 1 at a time, or 2). for the same reason, an extremely complex sproc that you don't want to open up.

Other than that...

Let's have some fun with sql



USE Northwind
GO

-- Just in Case
SELECT * INTO Orders_bkp FROM Orders

-- Lets Build the In Value Tables
SET NOCOUNT ON
CREATE TABLE EmpIn (EmployeeId int)
CREATE TABLE CustIn (CustomerId nchar(10))
GO

INSERT INTO EmpIn(EmployeeId)
SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4

INSERT INTO CustIn(CustomerId)
SELECT 'ALFKI' UNION ALL
SELECT 'ANATR' UNION ALL
SELECT 'ANTON' UNION ALL
SELECT 'AROUT'
GO

-- Let's smoke some cpu's

DECLARE @FETCH_STATUS99 int, @OrderId int, @EmployeeId int, @CustomerId nchar(10)

DECLARE myCursor99 CURSOR FOR SELECT OrderId FROM Orders
DECLARE myCursor98 CURSOR FOR SELECT EmployeeId FROM EmpIn
DECLARE myCursor97 CURSOR FOR SELECT CustomerId FROM CustIn

SELECT GetDate() AS systime, 'Starting Cursor Processing' AS sysmessage

OPEN myCursor99
FETCH NEXT FROM myCursor99 INTO @OrderId
SET @FETCH_STATUS99 = @@FETCH_STATUS

WHILE @FETCH_STATUS99 = 0
BEGIN
OPEN myCursor98
FETCH NEXT FROM myCursor98 INTO @EmployeeId
WHILE @@FETCH_STATUS = 0
BEGIN
IF EXISTS (SELECT * FROM Orders WHERE OrderId = @OrderID AND EmployeeId = @EmployeeId)
UPDATE Orders SET EmployeeId = @EmployeeId WHERE OrderId = @OrderId
FETCH NEXT FROM myCursor98 INTO @EmployeeId
END
CLOSE myCursor98

OPEN myCursor97
FETCH NEXT FROM myCursor97 INTO @CustomerId
WHILE @@FETCH_STATUS = 0
BEGIN
IF EXISTS (SELECT * FROM Orders WHERE OrderId = @OrderID AND CustomerId = @CustomerId)
UPDATE Orders SET CustomerId = @CustomerId WHERE OrderId = @OrderId
FETCH NEXT FROM myCursor97 INTO @CustomerId
END
CLOSE myCursor97
FETCH NEXT FROM myCursor99 INTO @OrderId
SET @FETCH_STATUS99 = @@FETCH_STATUS
END
CLOSE myCursor99

DEALLOCATE myCursor99
DEALLOCATE myCursor98
DEALLOCATE myCursor97

SELECT GetDate() AS systime, 'Endind Cursor Processing' AS sysmessage

-- And they way it should be done...

SELECT GetDate() AS systime, 'Starting Set Processing' AS sysmessage

UPDATE Orders SET EmployeeId = @EmployeeId WHERE EmployeeId IN (SELECT EmployeeId FROM EmpIn)
UPDATE Orders SET CustomerId = @CustomerId WHERE CustomerId IN (SELECT CustomerId FROM CustIn)

SELECT GetDate() AS systime, 'Starting Set Processing' AS sysmessage
GO

SET NOCOUNT OFF
DROP TABLE EmpIn
DROP TABLE CustIn
GO



Brett

8-)
Go to Top of Page

nr
SQLTeam MVY

12543 Posts

Posted - 2004-09-10 : 17:02:28
>> Ok, what does that mean?
Once you use a cursor you are restricted to row by row processing.
If you use a temp table to do the same thing you can still do set based operations on it - even if you have to process row by row at the end.

==========================================
Cursors are useful if you don't know sql.
DTS can be used in a similar way.
Beer is not cold and it isn't fizzy.
Go to Top of Page
   

- Advertisement -