2

this could be a stupid syntax error but I just keep reading my procedure but i cannot figure out where are my errors.

Msg 156, Level 15, State 1, Line 41
Incorrect syntax near the keyword 'FOR'.

Here is my code :

alter procedure LockReservation as
DECLARE @edition_id tinyint, @stockid  tinyint;
DECLARE @creservation CURSOR FOR select edition_id from reservation where (date_fin - GETUTCDATE()) <= 12;
open creservation;
while @@fetch_status = 0
BEGIN
    fetch creservation into @edition_id;
    DECLARE @cstock CURSOR 
        FOR select id from stock where edition_id = @edition_id;
    open cstock;
    while @@fetch_status = 0
    BEGIN
        fetch cstock into @stockid;
        select stock_id from location where location.stock_id = @stockid and archivage = 0
        if @@rowcount = 0
        BEGIN
             insert into stocks_reserves(id, date_ajout, usure, suppression, edition_id) 
                    Select id, date_ajout, usure, suppression, edition_id 
                from stock 
                where stock.id = @stockid
        END
    END
    CLOSE cstock
    DEALLOCATE cstock
END
CLOSE creservation
DEALLOCATE creservation

Can somebody help me ?

1
  • It's the line where i declare creservation Commented Mar 30, 2011 at 19:26

4 Answers 4

13

Don't use the @ symbol in your cursor names.

Sign up to request clarification or add additional context in comments.

3 Comments

Why? I accept that it works, but where is it documented?
@Manngo The documentation clearly shows that there is no "@" used for a cursor name. learn.microsoft.com/en-us/sql/t-sql/language-elements/…
The documentation doesn’t use @, but it doesn’t preclude it either. The thing is, you can declare and set a cursor variable separately: declare @something cursor; set @something = … ; but not in the same statement, which is something of a surprise.
3

Get rid of the cursor - use a set based solution.

Basically you are doing this:

insert into stocks_reserves
(id, date_ajout, usure, suppression, edition_id) 
Select id, date_ajout, usure, suppression, edition_id 
from stock 
where stock.id in
(
    select stock_id 
    from location 
    where location.stock_id in
    (
        select id 
        from stock 
        where edition_id in
        (
            select edition_id 
            from reservation 
            where (date_fin - GETUTCDATE()) <= 12
        )
    )
    and archivage = 0
)

You can replace the IN with an exists to process the insert faster.

Better still, do INNER JOIN for possibly the best performance.

2 Comments

+1 for this approach. Don't know if it really works for this particular case, but Dimitri can confirm. Anyway, the best is to avoid cursors as much as possible for best performance. the drawback is that debugging is way harder...
OK, Cursors are problematic, but the question was about a syntax error, not how to improve the code.
1

Name your cursor creservation instead of @creservation

Comments

1

Drop the @ symbol before your cursor name in the DECLARE @cstock CURSOR statement

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.