0

I have a large T-SQL query (I only put a part here because I very sure the rest is working nice):

 WHERE /*
                ******* missing filter *******
                this line should filter the risks by @LoggedInPersonID via role 
                ******************************
          AND */(@PropertyID IS NULL OR p.PropertyID = @PropertyID)
          AND (@PCodePattern IS NULL OR p.PCode LIKE @PCodePattern)
          AND (@ZipCodeIDS IS NULL 
                 OR p.ZipCodeID IN (@ZipCodeIDS))

You notice that @ZipCodeIDS is a list... Well, I populate this from code with some ids. When @ZipCodeIDS contains a SINGLE id it works perfectly but if I try to send multiple ids (eg: "14,15") it gives me error....

Do you have any clue?

Ps: Of course I made @ZIpCodeIDS varchar because we do not have array in T-SQL...

UPDATE: If I directly hardcode in the query: IN (14,11) it perfectly works... so somehow I do not correctly send this parameter from my code for multiple values I think it does not see "," as a separator...

UPDATE 2: Tried to split the lists and put the ids into a table... When zipCodeIDS has only one id the query works perfectly. For multiple ones, not... Do you see something strange on ELSE?

    IF @ZipCodeIDS IS NOT NULL
BEGIN
    IF CHARINDEX(',', @ZipCodeIDS) = 0
    BEGIN
        insert @listofIDS values(@ZipCodeIDS)
    END
    ELSE
    BEGIN
        WHILE CHARINDEX(',', @ZipCodeIDS) != 0
        BEGIN
            insert @listofIDS values(Left(@ZipCodeIDS, PatIndex(',', @ZipCodeIDS) - 1))
            SET @ZipCodeIDS = SUBSTRING(@ZipCodeIDS, CHARINDEX(',',@ZipCodeIDS)+1, LEN(@ZipCodeIDS) - CHARINDEX(',',@ZipCodeIDS))
        END
    END
END
Cristian Boariu
  • 9,603
  • 14
  • 91
  • 162

5 Answers5

3

Have a look at this article -

http://www.sommarskog.se/arrays-in-sql.html

It discusses a number of ways you could alter your query.

This question may also prove helpful -

Parameterize an SQL IN clause

Community
  • 1
  • 1
ipr101
  • 24,096
  • 8
  • 59
  • 61
2

You can't use IN like that. It's trying to look for p.ZipCodeID where the zip code is equal to '14, 15', in your example.

Instead, you'll have to compare p.ZipCodeID to each zip code you need, e.g.

... OR p.ZipCodeID=14 OR p.ZipCodeID=15

The alternative (which is less preferable) is to dynamically generate the SQL statement and then use EXEC to run it. The main problem with that, of course, is SQL injection.

Michael Todd
  • 16,679
  • 4
  • 49
  • 69
1
Declare @listofIDS table(zipcodeids varchar(10))

Declare @ZipCodeIDS varchar(100)
set  @ZipCodeIDS= '14,15'

set @ZipCodeIDS+= ','
;with cte as
(
select substring(@ZipCodeIDS, 1, charindex(',', @ZipCodeIDS) - 1) num, charindex(',', @ZipCodeIDS) pos
union all
select substring(@ZipCodeIDS, pos + 1, charindex(',', @ZipCodeIDS, pos +1) - pos - 1) num, charindex(',', @ZipCodeIDS, pos +1)
from cte
where charindex(',', @ZipCodeIDS, pos +1) > 0

)
INSERT @listofIDS 
select num from cte


.... or p.ZipCodeID in (select zipcodeids from @listofIDS) 

--------------------

Try this (remember to set all your variables):

Declare @ZipCodeIDS varchar(100)
set  @ZipCodeIDS= '14,15'

set @ZipCodeIDS+= ','
;with cte as
(
select cast(substring(@ZipCodeIDS, 1, charindex(',', @ZipCodeIDS) - 1) as int) num, charindex(',', @ZipCodeIDS) pos
union all
select cast(substring(@ZipCodeIDS, pos + 1, charindex(',', @ZipCodeIDS, pos +1) - pos - 1) as int) num, charindex(',', @ZipCodeIDS, pos +1)
from cte
where charindex(',', @ZipCodeIDS, pos +1) > 0
)

SELECT /*... rest of your query that was not included in the question. no colon, nor anything else, just your query plus the small alteration i made in the end
...
...*/
WHERE /*
                ******* missing filter *******
                this line should filter the risks by @LoggedInPersonID via role 
                ******************************
          AND */(@PropertyID IS NULL OR p.PropertyID = @PropertyID)
          AND (@PCodePattern IS NULL OR p.PCode LIKE @PCodePattern)
          AND (@ZipCodeIDS IS NULL 
                 OR p.ZipCodeID IN (select num from cte))
t-clausen.dk
  • 43,517
  • 12
  • 59
  • 92
0

Can you do DECLARE @ZipCodeIDS TABLE(id INT NOT NULL PRIMARY KEY) and then join this table?

a1ex07
  • 36,826
  • 12
  • 90
  • 103
  • Well, I already have that table...and I do join of course based on which ids from that table user has selected...using checkboxes.. – Cristian Boariu Aug 12 '11 at 21:49
0
 AND (@ZipCodeIDS IS NULL OR p.ZipCodeID IN (select z.ID from @ZipCodeIDS))

You state that SQL has no "array" but everything works in sets. Create a temporary table or a table variable and fill it with your zipcodeIDs

declare @ZipCodeIDs = TABLE ( ID int NOT NULL)

fill @ZipCodeIDs with the ints

then use your code as before

If you are trying to pass an array from your .net code to the databaes you can do this with a user defined table type in SQL server 2008.

Michael Christensen
  • 1,768
  • 1
  • 13
  • 11