Search code examples
sqlsql-servercountcursorprocedure

Procedure with cursor for counting a number of orders before a given date


Check if there are any orders before a given date (Date column). The procedure has a passing parameter "date" as date and another passing parameter "count". This parameter returns the number of orders before this date.

The simple way of doing it would be:

SELECT COUNT([Sales].[dbo].[Order].[Date])
FROM [Sales].[dbo].[Order]
WHERE [Sales].[dbo].[Order].[Date] >= '2019-03-11'

But unfortunately I have to use the procedure and the cursor. My attempt is this:

CREATE OR ALTER PROCEDURE OrderBeforeDate
    (@date date, 
     @count int OUT)
AS
BEGIN
    SET @count = 0;

    DECLARE cursor1 SCROLL CURSOR FOR
        SELECT [Sales].[dbo].[Order].[Date] 
        FROM [Sales].[dbo].[Order]
        FOR READ ONLY

    OPEN cursor1;

    FETCH NEXT FROM cursor1 INTO @date

    WHILE @@FETCH_STATUS = 0
    BEGIN
        IF @date <= '2019-03-11'
            SET @count = @count + 1;
    END

    CLOSE cursor1;
    DEALLOCATE cursor1;
END

DECLARE @count int

EXEC OrderBeforeDate @count OUT

PRINT 'Number of Orders after 2019-03-11'': ' + CAST(@count AS VARCHAR(10))

But I get the following error message:

Operand type collision: int is incompatible with date

I don't know what to do. Please give me a helping hand.


Solution

  • Thanks for all your input! I think it works now with the code like this:

    CREATE OR ALTER PROC OrderBeforeDate(@date date, @count int out)
    AS
    BEGIN
    
    SET @count = 0;
    
    DECLARE cursor1 scroll cursor for
    SELECT [Sales].[dbo].[Order].[Date] 
    FROM [Sales].[dbo].[Order]
    FOR READ ONLY
    
    OPEN cursor1;
    FETCH NEXT FROM cursor1 INTO @date
    WHILE @@FETCH_STATUS = 0
    BEGIN
    IF @date < '2019-03-11'
        SET @count = @count + 1;
        FETCH NEXT FROM cursor1 INTO @date
    END
    
    CLOSE cursor1;
    DEALLOCATE cursor1;
    
    END
    
    
    DECLARE @count int
    DECLARE @date date
    EXEC OrderBeforeDate @date, @count OUT
    
    PRINT 'Number of Orders before 2019-03-11: ' + CAST(@count AS VARCHAR(10))
    

    You're right that this method is way slower than the one I mentioned in the first place. (1 minute versus less than a second) Thanks everyone for your help!