WHERE IN (array of IDs)

后端 未结 9 1177
暖寄归人
暖寄归人 2020-11-28 11:16

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?

相关标签:
9条回答
  • 2020-11-28 11:30

    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.

    0 讨论(0)
  • 2020-11-28 11:32

    A superfast XML Method which requires no unsafe code or user defined functions :

    You can use a stored procedure and pass the comma separated list of Building IDs :

    Declare @XMLList xml
    SET @XMLList=cast('<i>'+replace(@buildingIDs,',','</i><i>')+'</i>' as xml)
    SELECT x.i.value('.','varchar(5)') from @XMLList.nodes('i') x(i))
    

    All credit goes to Guru Brad Schulz's Blog

    0 讨论(0)
  • 2020-11-28 11:35

    I use that approach and works for me.

    My variable act = my list of ID's at string.

    act = "1, 2, 3, 4"

     command = new SqlCommand("SELECT x FROM y WHERE x.id IN (@actions)", conn);    
     command.Parameters.AddWithValue("@actions", act);
     command.CommandText = command.CommandText.Replace("@actions", act);
    
    0 讨论(0)
  • 2020-11-28 11:36

    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).
    0 讨论(0)
  • 2020-11-28 11:43

    [WebMethod]

    public MiniEvent[] getAdminEvents(int buildingID, DateTime startDate)

    ...

    SqlParameter buildID= new SqlParameter("@buildingIDs", buildingIDs);

    Perhaps I'm being over detailed, but this method accepts a single int, not an array of ints. If you expect to pass in an array, you will need to update your method definition to have an int array. Once you get that array, you will need to convert the array to a string if you plan to use it in a SQL query.

    0 讨论(0)
  • 2020-11-28 11:50

    Visit T-SQL stored procedure that accepts multiple Id values for ideas on how to do this.

    0 讨论(0)
提交回复
热议问题