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
 General SQL Server Forums
 New to SQL Server Programming
 CURSOR: Last value inserts twice

Author  Topic 

kfluffie
Posting Yak Master

103 Posts

Posted - 2009-05-30 : 18:26:47
Hi!
See my code:
/***********************************
Author: Tomas Westerlund, 861117-1490
Date: 2009-04-18
Course: IV139V
Assignment: Projekt2, Uppgift21
***********************************/
ALTER PROCEDURE tillaga_recept (@antal_port int, @recept_id int)
AS

DECLARE @del_variabel decimal(8,2)
DECLARE @receptnamn varchar(100)

IF NOT EXISTS (SELECT * FROM dbo.Recept
WHERE id = @recept_id)
BEGIN
PRINT 'Recept Saknas!'
END

ELSE IF(@antal_port = 0)
BEGIN
PRINT 'Ska du verkligen räkna ut detta på 0 portioner?'
END




ELSE IF EXISTS (SELECT * FROM dbo.Recept
WHERE id = @recept_id)
BEGIN

SET @del_variabel = ((SELECT portioner FROM dbo.Recept WHERE id = @recept_id) / CAST(@antal_port as decimal(8,2)))

CREATE TABLE #recept
(ravaraID int,
antal decimal(8,2))


DECLARE @antal_cursor as decimal(8,2), @ravaraID int

DECLARE receptomvandling CURSOR READ_ONLY
FOR
SELECT I.id, (CAST(I.Antal as decimal(8,2)) / @del_variabel)
FROM dbo.Recept R
INNER JOIN dbo.Ingrediens I ON I.recept_id = R.ID
INNER JOIN dbo.Råvara RV ON RV.id = I.råvara_id
WHERE R.id = @recept_id


OPEN receptomvandling

FETCH NEXT FROM receptomvandling
INTO @ravaraID, @antal_cursor
INSERT INTO #recept
VALUES (@ravaraID, @antal_cursor)


WHILE (@@FETCH_STATUS = 0)
BEGIN

FETCH NEXT FROM receptomvandling
INTO @ravaraID, @antal_cursor
SELECT * FROM #recept
PRINT 'Fetchstatus: ' + CAST(@@FETCH_STATUS as char(2))
INSERT INTO #recept
VALUES (@ravaraID, @antal_cursor)
SELECT * FROM #recept
PRINT 'Fetchstatus: ' + CAST(@@FETCH_STATUS as char(2))
END

CLOSE receptomvandling
DEALLOCATE receptomvandling



END

SELECT * FROM #recept


I have some "debugging" in the code also (PRINT Fetchstatus):
(1 row(s) affected)

(1 row(s) affected)
Fetchstatus: 0

(1 row(s) affected)

(2 row(s) affected)
Fetchstatus: 0

(2 row(s) affected)
Fetchstatus: 0

(1 row(s) affected)

(3 row(s) affected)
Fetchstatus: 0

(3 row(s) affected)
Fetchstatus: 0

(1 row(s) affected)

(4 row(s) affected)
Fetchstatus: 0

(4 row(s) affected)
Fetchstatus: -1

(1 row(s) affected)

(5 row(s) affected)
Fetchstatus: -1

(5 row(s) affected)

(1 row(s) affected)


Why does it insert the last record when @@FETCHSTATUS != 0?

Thanks in advance!

Best Regards,
Tomas

TG
Master Smack Fu Yak Hacker

6065 Posts

Posted - 2009-05-30 : 19:05:30
The WHILE condition is only re-evaluated at the END statement.
I don't think you need a cursor for this. Why don't you simply INSERT all the rows into #receipt at once?

But if you use a cursor it is better to structure it like this:

declare crs for ...
open crs
fetch next from crs into ...
while @@fetch_status = 0
begin
<do all your "stuff" here>

fetch next from crs into ...
end


Be One with the Optimizer
TG
Go to Top of Page

kfluffie
Posting Yak Master

103 Posts

Posted - 2009-05-30 : 20:19:02
quote:
Originally posted by TG

The WHILE condition is only re-evaluated at the END statement.
I don't think you need a cursor for this. Why don't you simply INSERT all the rows into #receipt at once?

But if you use a cursor it is better to structure it like this:

declare crs for ...
open crs
fetch next from crs into ...
while @@fetch_status = 0
begin
<do all your "stuff" here>

fetch next from crs into ...
end


Be One with the Optimizer
TG



Good question!
The previous assignments (it is for a course) they wanted us to use Cursors for practice so I had the cursor imprinted into my head but the cursor wasn't nescessary however!

The new solution:

ELSE IF EXISTS (SELECT * FROM dbo.Recept
WHERE id = @recept_id)
BEGIN

SET @del_variabel = ((SELECT portioner FROM dbo.Recept WHERE id = @recept_id) / CAST(@antal_port as decimal(8,2)))

CREATE TABLE #recept
(ravaraID int,
antal decimal(8,2))


INSERT INTO #recept
SELECT I.id, (CAST(I.Antal as decimal(8,2)) / @del_variabel)
FROM dbo.Recept R
INNER JOIN dbo.Ingrediens I ON I.recept_id = R.ID
INNER JOIN dbo.Råvara RV ON RV.id = I.råvara_id
WHERE R.id = @recept_id


END



Thanks for the help!

Best Regards,
KF
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2009-05-31 : 03:08:33
Lägg till denna felkontroll...
ELSE IF @antal_port < 0 OR @antal_port > 19
BEGIN
PRINT 'Är du full eller?'
END



And for those of you who doesn't understand Swedish
ELSE IF @antal_port < 0 OR @antal_port > 19
BEGIN
PRINT 'Are you drunk?'
END


E 12°55'05.63"
N 56°04'39.26"
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2009-05-31 : 03:09:42
[code] OPEN receptomvandling

FETCH NEXT FROM receptomvandling
INTO @ravaraID, @antal_cursor

PRINT 'Fetchstatus: ' + CAST(@@FETCH_STATUS as char(2))

WHILE (@@FETCH_STATUS = 0)
BEGIN
INSERT INTO #recept
VALUES (@ravaraID, @antal_cursor)

SELECT * FROM #recept

FETCH NEXT FROM receptomvandling
INTO @ravaraID, @antal_cursor

PRINT 'Fetchstatus: ' + CAST(@@FETCH_STATUS as char(2))
END

CLOSE receptomvandling
DEALLOCATE receptomvandling[/code]

E 12°55'05.63"
N 56°04'39.26"
Go to Top of Page
   

- Advertisement -