views:

116

answers:

4

I have a T-SQL stored proc that supplies a good amount of data to a grid on a .NET page....so much so that I put choices at the top of the page for "0-9" and each letter in the alphabet so that when the user clicks the letter I want to filter my results based on results that begin with that first letter. Let's say we're using product names. So if the user clicks on "A" I only want my stored proc to return results where SUBSTRING(ProductName, 1, 1) = "A".

Where I'm getting hung up is on product names that begin with a number. In that case I want to fetch all ProductName values where ISNUMERIC(SUBSTRING(ProductName, 1, 1)) = 1. I'm using an input parameter called @FL. @FL will either be a zero (we have few products that begin with numerics, so I lump them all together this way).

Of course there's also the alternative of WHERE SUBSTRING(ProductName, 1, 1) IN ('0', '1', '2'.....) but even then, I've never been able to devise a CASE statement that will do an = on one evaluation and an IN statement for the other.

Here's what I have in my proc for the CASE part of my WHERE clause. It doesn't work, but it may be valuable if only from a pseudocode standpoint.

Thanks in advance for any ideas you may have.

AND CASE @FL
    WHEN "0" THEN
    CASE WHEN @FL = "0" THEN
        isnumeric(substring(dbo.AssnCtrl.Name, 1, 1)) = 1
    ELSE
        SUBSTRING(dbo.AssnCtrl.Name, 1, 1) = @FL            
    END
END

* I know that this use of the CASE statement is "non-standard", but I found it online and thought it had some promise. But attempts to use a single CASE statement yielded the same result (an error near '=').

A: 

Why not just use Like operator ?

   Where dbo.AssnCtrl.Name Like @FL + '%' 

When they select the Any Number option, pass in @FL as '[0-9]'

(I assume you have an index on this name column ?)

Charles Bretana
Like your thinking, but given that @FL will be 0 or a letter, how would that work for values where the first character is 1-9? I don't see how that works for numerics.
Mike
see edit, Like can accept a range of values inside of brackets...
Charles Bretana
@Charles - because there are so few numeric results, I've combined 0-9 in my page link and an @FL value of 0 is represented for *any* product that begins with a numeric character....make sense?
Mike
A-ha! Now I see your point! I wasn't aware of the range possiblities of LIKE. So I can say AND substring(assnctrl.name, 1, 1) LIKE CASE when @FL = '0' then '[0-9]' else @FL.
Mike
Or you can change your stored procedure to edit the incoming paramenter: if @FL='0' Set @FL='[0-9]'. This lets you get rid of the slow CASE statement.
Bill
@Mike, you don't even need the `Substring()`, that's the point of the wildcard. It will match anything that starts with @FL Use `Where assnctrl.name Like @FL + '%'`
Charles Bretana
Oh, I like that idea!
Mike
+1  A: 

To steal a bit from Charles:

AND Substring(dbo.AssnCtrl.Name, 1, 1) Like
  CASE WHEN @FL = '0' THEN '[0-9]'
    ELSE @FL            
  END
Bill
Doh. Comments in Charles answer updated to include my solution.
Bill
+1: Tested on SS2005, works for me.
OMG Ponies
better still is to eliminate the call to substring function. `AND dbo.AssnCtrl.Name Like CASE @FL WHEN '0' THEN '[0-9]' ELSE @FL END + '%' `
Charles Bretana
A: 

Have you tried

AND (
        isnumeric(substring(dbo.AssnCtrl.Name, 1, 1)) = 1
    or
        SUBSTRING(dbo.AssnCtrl.Name, 1, 1) = @FL    )

this works for me:

select * from casefile where
isnumeric(substring(pmin,1,1)) = 1
or 
substring(pmin,1,1) = 'a'
Beth
A: 

Thanks for the great suggestions everyone! Cheers.

Mike