Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / ASP.NET / General / October 2007

Tip: Looking for answers? Try searching our database.

Parameterized SQL with IN Clause

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Asif - 20 Oct 2007 13:56 GMT
Hi all,

I am working on a web site using SQL Server 2005 and ASP.NET using
VB.NET.

I am running the following SQL:

Dim oReader As SqlDataReader
Dim IDs As String = "1,2,3"
Dim strSQL As String = "SELECT * FROM Author WHERE ID IN (@IDs)"
' ID field is Primary Key in Author Table

Dim objCmd As New SqlCommand
objCmd.CommandText = strSQL
objCmd.CommandType = CommandType.Text
objCmd.Parameters.Add(New SqlParameter("@TITLE", IDs)
objCmd.Connection = MyConnection
oReader = objCmd.ExecuteReader(CommandBehavior.CloseConnection)
if oReader.HasRows() Then
 Do While oReader.Read
     MessageBox.Show(oReader.Item(1))
 Loop
End If

Above code executes without any error but with no resutls.

Can any one tell me about how to use IN Clause in Parameterized SQL.

Thanks
Alexey Smirnov - 20 Oct 2007 21:20 GMT
> Hi all,
>
[quoted text clipped - 25 lines]
>
> Thanks

you can use it with IN clause

change you code to something like this

Dim strSQL As String = "SELECT * FROM Author WHERE ID IN (" + IDs +
")"

and get rid of SqlParameter
Alexey Smirnov - 20 Oct 2007 21:27 GMT
> > Hi all,
>
[quoted text clipped - 36 lines]
>
> - Show quoted text -

oh, sorry, a typo: you canNOT use it with IN clause
Eliyahu Goldin - 21 Oct 2007 13:46 GMT
The reason is because the value of @IDs is considered as one element in the
IN list. It is possible to make the IN list in run-time in form

WHERE ID IN (@id1, @id2 ...)"

Signature

Eliyahu Goldin,
Software Developer
Microsoft MVP [ASP.NET]
http://msmvps.com/blogs/egoldin
http://usableasp.net

>> > Hi all,
>>
[quoted text clipped - 38 lines]
>
> oh, sorry, a typo: you canNOT use it with IN clause
Cowboy (Gregory A. Beamer) - 21 Oct 2007 16:40 GMT
You cannot do it the way you are attempting to do it. There are a couple of
ways around this.

The first is the one shown in your discussion with Alexy, where you
concatenate the ids string to the SQL string. This is fairly simple, but
cannot be done with a single @ids parameter, as you are not truly
parameterizing at this time. NOTE: If you adopt this method, you have the
potential of SQL injection.

Another method is to pass XML into SQL Server, with each ID in a separate
element. You can then join to the XML in a stored procedure and return the
results. This is similar to the IN, but immune from SQL injection.

Signature

Gregory A. Beamer
MVP, MCP: +I, SE, SD, DBA

*************************************************

| Think outside the box!

*************************************************
> Hi all,
>
[quoted text clipped - 25 lines]
>
> Thanks
Mark Rae [MVP] - 21 Oct 2007 18:55 GMT
> Another method is to pass XML into SQL Server, with each ID in a separate
> element. You can then join to the XML in a stored procedure and return the
> results. This is similar to the IN, but immune from SQL injection.

There's a really good article on that here:
http://www.codeproject.com/sqlrs/PassingArraysSQLParameter.asp

Signature

Mark Rae
ASP.NET MVP
http://www.markrae.net

Lloyd Sheen - 21 Oct 2007 19:29 GMT
>> Another method is to pass XML into SQL Server, with each ID in a separate
>> element. You can then join to the XML in a stored procedure and return
>> the results. This is similar to the IN, but immune from SQL injection.
>
> There's a really good article on that here:
> http://www.codeproject.com/sqlrs/PassingArraysSQLParameter.asp

I have been following this thread and one thing that has not been mentioned
is that if the method used depends on dynamically creating the SQL then you
must ensure that characters that will break the SQL are not inserted.  While
this is not as bad as a SQL Injection I am sure your users don't want to see
a msg about a SQL syntax error that they unwittingly created.

LS
Mark Rae [MVP] - 21 Oct 2007 19:46 GMT
> I have been following this thread and one thing that has not been
> mentioned is that if the method used depends on dynamically creating the
> SQL then you must ensure that characters that will break the SQL are not
> inserted.

That's true, but doesn't apply to the native XML datatype method...

Signature

Mark Rae
ASP.NET MVP
http://www.markrae.net

MDoyle - 22 Oct 2007 12:06 GMT
> > I have been following this thread and one thing that has not been
> > mentioned is that if the method used depends on dynamically creating the
[quoted text clipped - 6 lines]
> Mark Rae
> ASP.NET MVPhttp://www.markrae.net

I had this question months ago, and here is an article I came across
that helped me a lot:
http://www.sommarskog.se/dynamic_sql.html

It shows how to do (among other things) exactly what you are trying to
accomplish.
mark4asp - 22 Oct 2007 15:38 GMT
> Hi all,
>
[quoted text clipped - 25 lines]
>
> Thanks

I use an IN clause with a parameterized query in a similar scenario to
the one you want to use. However I get the results for my in clause
from a function returning a single column.  I include it below. This
takes a string of integer comma separated values as input and returns
a table with a single column.

Here is a snippet of SQL using this function:

ConsultantID In (Select * From
dbo.CSV_IntegersToSingleColumn(@ConsultantIDs))

-- PS: Homage to the guy who wrote this. Sorry I lost the Url where it
came from.
-- Convert string of integer comma separated values (input) to a table
of integers (return value).
ALTER FUNCTION [dbo].[CSV_IntegersToSingleColumn]
(
   @cslist VARCHAR(8000)
)
RETURNS @t TABLE
(
   Item VARCHAR(64)
)
BEGIN
   DECLARE @spot SMALLINT, @str VARCHAR(8000), @sql VARCHAR(8000)

   WHILE @cslist <> ''
   BEGIN
       SET @spot = CHARINDEX(',', @cslist)
       IF @spot > 0
           BEGIN
               SET @str = LEFT(@cslist, @spot - 1)
               SET @cslist = RIGHT(@cslist, LEN(@cslist) - @spot)
           END
       ELSE
           BEGIN
               SET @str = @cslist
               SET @cslist = ''
           END
       INSERT @t SELECT @str
   END
   RETURN
END
Mark Rae [MVP] - 22 Oct 2007 15:56 GMT
> ConsultantID In (Select * From
> dbo.CSV_IntegersToSingleColumn(@ConsultantIDs))

What happens if you want *all* records irrespective of ConsultantID...?

Signature

Mark Rae
ASP.NET MVP
http://www.markrae.net

mark4asp - 23 Oct 2007 03:46 GMT
> > ConsultantID In (Select * From
> > dbo.CSV_IntegersToSingleColumn(@ConsultantIDs))
[quoted text clipped - 4 lines]
> Mark Rae
> ASP.NET MVPhttp://www.markrae.net

Mark, I don't understand your question. Is the question a reference to
the
snippet of code I wrote.  I just wrote something to put the function
in context.
I should have read the OPs first post (again) than I would've given
him the
query he wanted.

The function just converts a string of CSV integers to a column so
that it
can be used in a subquery (or even a JOIN). It works with SQL Server
2005
but maybe not with 2000. It depends on whether 2000 allows functions
to return a table. I suspect it doesn't. Play around with it. I've
never had
a problem with it in practice.
Mark Rae [MVP] - 23 Oct 2007 09:35 GMT
> Mark, I don't understand your question.

Supposing you have a stored procedure which takes the "array" parameter -
it's impossible to nullify this without writing dynamic SQL in the SP...

E.g. supposing you have a table with 1,000 rows, and the second column is an
integer called StatusID.

You write a stored procedure with an "array" parameter containing one or
more StatusID values in a CSV string.

1,9,13 returns all the rows where the StatusID is 1, 9 or 13 - obviously.

But what if you want *all* the rows? You can't pass a NULL value into the
"array" parameter without writing some dynamic SQL in the stored
procedure...

You could pass in an array containing all the StatusID values, I suppose,
but that would be extremely inefficient...

Signature

Mark Rae
ASP.NET MVP
http://www.markrae.net

Anthony Jones - 23 Oct 2007 09:43 GMT
> > > ConsultantID In (Select * From
> > > dbo.CSV_IntegersToSingleColumn(@ConsultantIDs))
[quoted text clipped - 21 lines]
> never had
> a problem with it in practice.

That function works fine in SQL 2000.  Personally I prefer the XML approach
since it has wider application but XML is slower and awkward under 2000.

Signature

Anthony Jones - MVP ASP/ASP.NET

Mark Rae [MVP] - 23 Oct 2007 09:48 GMT
> Personally I prefer the XML approach since it has wider application

Me too...

Signature

Mark Rae
ASP.NET MVP
http://www.markrae.net

mark4asp - 22 Oct 2007 15:56 GMT
> > Dim strSQL As String = "SELECT * FROM Author WHERE ID IN (@IDs)"
> > ...
[quoted text clipped - 34 lines]
>
> - Show quoted text -

This will be your query:

SELECT * FROM Author WHERE ID IN
 (Select * From dbo.CSV_IntegersToSingleColumn(@IDs))

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.