tags:

views:

60

answers:

5

May not have been the best title but anyways..

I have a stored procedure which until now had 1 optional parameter which I easily solved with 1 if statement. Now it has 2 which brings it up to 4 if statements. I would like to know if there is a better way to write a query then the following. Especially if/when a variable count goes up to 4 or 5.

I am looking for an easier way to add this new ignoreTheseIds variable without having to add 2 more if/else statements.

ALTER PROCEDURE [dbo].[SomeQuery]
    @StartingDate varchar(10) = '1/1/1900',
    @EndingDate varchar(10) = NOW,
    @LimitToTheseIds varchar(MAX) = ''
    @IgnoreTheseIds varchar(MAX) = ''
AS

BEGIN
    SET NOCOUNT ON;

    IF @LimitTo = ''
    BEGIN
        SELECT id1, col2
        FROM Table1 as T
        WHERE SomeDateTime <= @EndDate
          AND SomeDateTime >= @StartDate
    END
    ELSE
    BEGIN
        SELECT id1, col2
        FROM Table1 as T
        WHERE SomeDateTime <= @EndDate
            AND SomeDateTime >= @StartDate
            AND @LimitToTheseIds LIKE '%|' + CAST(id1 as varchar) + '|%'
    END
END

Hope I didn't mess anything up when changing the var names...

A: 

When I've had to write larger SPROCS like this, I've added a "Type" variable that would go to a particular statement within the SPROC. For instance:

@queryType = 'A'

if @queryType = 'A'
 begin
  --do query A
 end

if @queryType = 'B'
 begin
  --do query B
 end

--etc.

It ended up being a little cleaner than having multiple if trees.

Aaron
Indeed a bit easier to read but I would still end up having 4 different versions correct?
corymathews
Yes, I just find this easier to read by separating the queries a little more.
Aaron
A: 

You can use the CASE statement for this, although you'll need to check to see whether you take efficiency hits by so doing. Something like this:

ALTER PROCEDURE [dbo].[SomeQuery]
    @StartingDate varchar(10) = '1/1/1900',
    @EndingDate varchar(10) = NOW,
    @LimitToTheseIds varchar(MAX) = ''
    @IgnoreTheseIds varchar(MAX) = ''
AS

BEGIN
    SET NOCOUNT ON;

    SELECT id1, col2
    FROM Table1 as T
    WHERE SomeDateTime <= @EndDate
        AND SomeDateTime >= @StartDate
        AND @LimitToTheseIds LIKE CASE WHEN @LimitToTheseIds = '' THEN '' ELSE '%|' + CAST(id1 as varchar) + '|%' END
        AND @IgnoreTheseIds LIKE CASE WHEN @IgnoreTheseIds = '' THEN '' ELSE /*something appropriate here*/
END

etc.

mwigdahl
+2  A: 

You can check to see if anything is passed in at all:

ALTER PROCEDURE [dbo].[SomeQuery] 
    @StartingDate varchar(10) = '1/1/1900', 
    @EndingDate varchar(10) = NOW, 
    @LimitToTheseIds varchar(MAX) = '' 
    @IgnoreTheseIds varchar(MAX) = '' 
AS 

BEGIN 
    SET NOCOUNT ON; 

    SELECT id1, col2 
    FROM Table1 as T 
    WHERE SomeDateTime <= @EndDate 
        AND SomeDateTime >= @StartDate 
        AND (@LimitToTheseIds LIKE '%|' + CAST(id1 as varchar) + '|%' 
        OR @LimitToTheseId = '')
END 
Jeff Hornby
ah hell forgot about this little trick. Thanks.
corymathews
A: 
  SELECT id1, col2
FROM Table1 as T
WHERE SomeDateTime <= @EndDate
    AND SomeDateTime >= @StartDate
AND (@LimitToTheseIds IS NULL OR @LimitToTheseIds LIKE '%|' + CAST(id1 as varchar) + '|%')
sadboy
+2  A: 

this is the most comprehensive article on dynamic search condition that I've ever come across:

http://www.sommarskog.se/dyn-search.html

KM