Using stored procedure or not?

Hi,

I have a table which consists of:
-an id (primary key)
-a type
-a subtype
-a userid

Depending the type and subtype I have to fetch records in other tables. This has to be for one user, grouped by each type/subtype

For instance:
type= 1 and subtype=1;
type=1 and subtype=2;
type=2;
type=3 and subtype=3;
type=3 and subtype=4;
type=4 and subtype= between 5 and 10

I tried creating a stored procedure, with cursor in it, but it is only returning the first row.

IF EXISTS (SELECT name
FROM sysobjects
WHERE name = N'test_with_cursor'
AND type = 'P')
DROP PROCEDURE test_with_cursor
GO

CREATE PROCEDURE test_with_cursor
@StartDate DateTime, @userid INTEGER
AS
DECLARE MY_USER_CURSOR Cursor
FOR
SELECT typeid, subtypeid
FROM items
where userid = @userid

Open MY_USER_CURSOR

DECLARE @v_typeid integer
DECLARE @v_subtypeid integer

Fetch NEXT FROM MY_USER_CURSOR INTO @v_typeid, @v_subtypeid
While (@@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)

Select @v_planningitemsubtypeid

FETCH NEXT FROM MY_USER_CURSOR INTO @v_typeid, @v_subtypeid
END
CLOSE MY_USER_CURSOR
DEALLOCATE MY_USER_CURSOR
GO

execute test_with_cursor'2006-03-30','99'
go

Is this the right approach Thx


Answer this question

Using stored procedure or not?

  • Gusbin

    Hi Louis, Thank you so much for your input!

    Frankly, I have to say that your suggested code does look much messier. But I suppose for keeping performance good, this is a step which I'll have to take.

    Your assumption regarding @v_ being variables is correct.

    The reason why I used a cursor was because I have to loop over multiple records. I don't see this in your code. You are saying something about 'letting SQL server optimizing the looping',... what do you exactly mean by that

    Thank you for the help


  • psyjon

    It's not clear what the problem is. Are you saying the resultset is incorrect What is it you're trying to accomplish

    One problem i see is that you're selecting @v_planningitemsubtypeid, which isn't defined nor fetched in your cursor.


  • srilalitha

    Hi Greg,

    Thank you for the response!

    I must say I wasn't very clear in my first message, sorry about that.

    Without going too much in detail: the main problem was that depending a number in 2 columns the output should be different. (looking up other data in other tables)

    But hooray, I managed to find it: Instead of using a stored procedure, I've created a function with 2 parameters. The great thing is I can do a select * from <function> I've created.

    However, I'm still not sure if I could have done the same in a stored procedure

    For completness of this thread I'll post the procedure here. I've to admit I didn't knew I could declare a RETURNS value with type table.

    CREATE FUNCTION test_with_cursor
    (
    @whenDate DateTime,
    @userid INTEGER
    )

    RETURNS @Results TABLE
    (
    timeconsumed int,
    description varchar(80)
    )

    AS
    BEGIN

    --declare some variables

    --declare the cursor

    --Open the cursor

    --fetch next record from cursor

    --iterate through cursor

    if @v_planningitemtypeid = 1 and @v_planningitemsubtypeid = 1
    begin

    --do this
    end

    if @v_planningitemtypeid = 1 and @v_planningitemsubtypeid = 2
    begin
    -- do this
    end

    if @v_planningitemtypeid = 2
    begin

    -- do this
    end

    if @v_planningitemtypeid = 3 and (@v_planningitemsubtypeid = 3 or @v_planningitemsubtypeid = 4 or @v_planningitemsubtypeid = 5)
    begin
    -- do this
    end

    if @v_planningitemtypeid = 4
    begin

    -- do this
    end


    --fetch next record
    END
    --close record

    RETURN
    END


  • Haroon_S

    when you execute a statement like:

    select sum (column1 + column2)
    from table

    this is the same as a cursor over

    select column1, column2
    from table

    and in each iteration doing

    select @runningTotal = @runningTotal + @column1 + @column2

    Just in a more optimized way. Clearly whether this pertains to your exact situation depends on what happens in the <--do this> code of your function, but since the output is a single table, it is more than likely possible to do this in one statement. Can you share what --do this expands to



  • KKL

    Generally speaking this is not really good for performance.. The different branches can be problematic for optimizing. But, if the data is not too large, maybe not a performance issue.

    I will say this, you could most likely build your entire loop, fetches, etc into a single select statement, depending on just how complex the branches are.

    Something along the lines of:

    insert into @results --assuming @v_ meant that it was a variable

    select case when planningitemtypeid = 1 and planningitemsubtypeid = 1
    then something
    when planningitemtypeid = 1 and planningitemsubtypeid = 2
    then something else

    ...........

    else blah end as timeconsumed,

    case when planningitemtypeid = 1 and planningitemsubtypeid = 1
    then something textual
    when planningitemtypeid = 1 and planningitemsubtypeid = 2
    then something else textual

    ...........

    else blah end as description

    FROM --most likely the rest of the query exactly like the CURSOR declaration

    It will look much messier, and will take wrapping your head around (if you don't immediately see it) but unless the calculations are just way out there (and if you can do it in a function that isn't likely) the savings might be great. The overhead of the declared cursor can be costly versus letting SQL Server optimize the looping...

    Just an idea.



  • Using stored procedure or not?