Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WHERE IN (array of IDs)

I have webservice which is passed an array of ints. I'd like to do the select statement as follows but keep getting errors. Do I need to change the array to a string?

[WebMethod] public MiniEvent[] getAdminEvents(int buildingID, DateTime startDate) {         command.CommandText = @"SELECT id,                             startDateTime, endDateTime From                             tb_bookings WHERE buildingID IN                             (@buildingIDs) AND startDateTime <=                             @fromDate";      SqlParameter buildID = new SqlParameter("@buildingIDs", buildingIDs); } 
like image 358
user17510 Avatar asked Oct 08 '08 10:10

user17510


People also ask

How do I query an array in MySQL?

Following is an elementary syntax structure to code for MySQL WHERE IN Array command in MySQL server to fetch information using array values and WHERE IN clause: SELECT ColumnName1, ColumnName2, …., ColumnNameNFROM TableNameWHERE ColumnName1 IN(ColumnName1_Value1, ColumnName1_Value2, ColumnName1_Value3);

How to find object in array JavaScript?

To find an object in a JavaScript array, use the array. find() method. The find() method searches the provided object inside the array, and if the method finds it, it returns the object.

How to search for id from a object in JavaScript?

Use the find() method: myArray. find(x => x.id === '45').

How can we fetch data from database and store in array in PHP?

Data can be fetched from MySQL tables by executing SQL SELECT statement through PHP function mysql_query. You have several options to fetch data from MySQL. The most frequently used option is to use function mysql_fetch_array(). This function returns row as an associative array, a numeric array, or both.


2 Answers

You can't (unfortunately) do that. A Sql Parameter can only be a single value, so you'd have to do:

WHERE buildingID IN (@buildingID1, @buildingID2, @buildingID3...) 

Which, of course, requires you to know how many building ids there are, or to dynamically construct the query.

As a workaround*, I've done the following:

WHERE buildingID IN (@buildingID)  command.CommandText = command.CommandText.Replace(   "@buildingID",    string.Join(buildingIDs.Select(b => b.ToString()), ",") ); 

which will replace the text of the statement with the numbers, ending up as something like:

WHERE buildingID IN (1,2,3,4) 
  • Note that this is getting close to a Sql injection vulnerability, but since it's an int array is safe. Arbitrary strings are not safe, but there's no way to embed Sql statements in an integer (or datetime, boolean, etc).
like image 50
Mark Brackett Avatar answered Sep 25 '22 08:09

Mark Brackett


First you're going to need a function and a sproc. The function will split your data and return a table:

CREATE function IntegerCommaSplit(@ListofIds nvarchar(1000)) returns @rtn table (IntegerValue int) AS begin While (Charindex(',',@ListofIds)>0) Begin     Insert Into @Rtn      Select ltrim(rtrim(Substring(@ListofIds,1,Charindex(',',@ListofIds)-1)))     Set @ListofIds = Substring(@ListofIds,Charindex(',',@ListofIds)+len(','),len(@ListofIds)) end Insert Into @Rtn      Select  ltrim(rtrim(@ListofIds)) return  end 

Next you need a sproc to use that:

create procedure GetAdminEvents      @buildingids nvarchar(1000),     @startdate datetime as SELECT id,startDateTime, endDateTime From             tb_bookings t INNER JOIN  dbo.IntegerCommaSplit(@buildingids) i on i.IntegerValue = t.id  WHERE startDateTime <= @fromDate 

Finally, your code:

[WebMethod]         public MiniEvent[] getAdminEvents(int[] buildingIDs, DateTime startDate)         command.CommandText = @"exec GetAdminEvents";  SqlParameter buildID= new SqlParameter("@buildingIDs", buildingIDs); 

That goes way beyond what your question asked but it will do what you need.

Note: should you pass in anything that's not an int, the whole database function will fail. I leave the error handling for that as an exercise for the end user.

like image 24
Josef Avatar answered Sep 22 '22 08:09

Josef