WHERE IN (array of IDs)

后端 未结 9 1178
暖寄归人
暖寄归人 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:50

    You can use this. Execute in SQLServer to create a function on your DB (Only once):

    IF EXISTS(
        SELECT *
        FROM sysobjects
        WHERE name = 'FN_RETORNA_ID_FROM_VARCHAR_TO_TABLE_INT')
    BEGIN
        DROP FUNCTION FN_RETORNA_ID_FROM_VARCHAR_TO_TABLE_INT
    END
    GO
    
    CREATE FUNCTION [dbo].FN_RETORNA_ID_FROM_VARCHAR_TO_TABLE_INT (@IDList VARCHAR(8000))
    RETURNS
        @IDListTable TABLE (ID INT)
    AS
    BEGIN
    
        DECLARE
            --@IDList VARCHAR(100),
            @LastCommaPosition INT,
            @NextCommaPosition INT,
            @EndOfStringPosition INT,
            @StartOfStringPosition INT,
            @LengthOfString INT,
            @IDString VARCHAR(100),
            @IDValue INT
    
        --SET @IDList = '11,12,113'
    
        SET @LastCommaPosition = 0
        SET @NextCommaPosition = -1
    
        IF LTRIM(RTRIM(@IDList)) <> ''
        BEGIN
    
            WHILE(@NextCommaPosition <> 0)
            BEGIN
    
                SET @NextCommaPosition = CHARINDEX(',',@IDList,@LastCommaPosition + 1)
    
                IF @NextCommaPosition = 0
                    SET @EndOfStringPosition = LEN(@IDList)
                ELSE
                    SET @EndOfStringPosition = @NextCommaPosition - 1
    
                SET @StartOfStringPosition  = @LastCommaPosition + 1
                SET @LengthOfString = (@EndOfStringPosition + 1) - @StartOfStringPosition
    
                SET @IDString =  SUBSTRING(@IDList,@StartOfStringPosition,@LengthOfString)                  
    
                IF @IDString <> ''
                    INSERT @IDListTable VALUES(@IDString)
    
                SET @LastCommaPosition = @NextCommaPosition
    
            END --WHILE(@NextCommaPosition <> 0)
    
        END --IF LTRIM(RTRIM(@IDList)) <> ''
    
        RETURN
    
    ErrorBlock:
    
        RETURN
    
    END --FUNCTION
    

    After create the function you have to call this on your code:

    command.CommandText = @"SELECT id,
                            startDateTime, endDateTime From
                            tb_bookings WHERE buildingID IN
                            (SELECT ID FROM FN_RETORNA_ID_FROM_VARCHAR_TO_TABLE_INT(@buildingIDs))) AND startDateTime <=
                            @fromDate";
    
    command.Parameters.Add(new SqlParameter(){
                               DbType = DbType.String,
                               ParameterName = "@buildingIDs",
                               Value = "1,2,3,4,5" //Enter the parameters here separated with commas
                           });
    

    This function get the text inner commas on "array" and make an table with this values as int, called ID. When this function is on you DB you can use in any project.


    Thanks to Microsoft MSDN.

    Igo S Ventura

    Microsoft MVA

    Sistema Ari de Sá

    igo1-2@hotmail.com

    P.S.: I'm from Brazil. Apologize my english... XD

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

    Here's a Linq solution I thought up. It'll automatically insert all items in the list as parameters @item0, @item1, @item2, @item3, etc.

    [WebMethod]
    public MiniEvent[] getAdminEvents(Int32[] buildingIDs, DateTime startDate)
    {
        // Gets a list with numbers from 0 to the max index in buildingIDs,
        // then transforms it into a list of strings using those numbers.
        String idParamString = String.Join(", ", (Enumerable.Range(0, buildingIDs.Length).Select(i => "@item" + i)).ToArray());
        command.CommandText = @"SELECT id,
                            startDateTime, endDateTime From
                            tb_bookings WHERE buildingID IN
                            (" + idParamString + @") AND startDateTime <=
                            @fromDate";
        // Reproduce the same parameters in idParamString 
        for (Int32 i = 0; i < buildingIDs.Length; i++)
                command.Parameters.Add(new SqlParameter ("@item" + i, buildingIDs[i]));
        command.Parameters.Add(new SqlParameter("@fromDate", startDate);
        // the rest of your code...
    }
    
    0 讨论(0)
  • 2020-11-28 11:57

    NOTE: I am not generally for using unparameterized queries. IN THIS INSTANCE, however, given that we are dealing with an integer array, you could do such a thing and it would be more efficient. However, given that everyone seems to want to downgrade the answer because it doesn't meet their criteria of valid advice, I will submit another answer that performs horribly but would probably run in LINK2SQL.

    Assuming, as your question states, that you have an array of ints, you can use the following code to return a string that would contain a comma delimited list that SQL would accept:

    private string SQLArrayToInString(Array a)
    {
     StringBuilder sb = new StringBuilder();
     for (int i = 0; i < a.GetUpperBound(0); i++)
      sb.AppendFormat("{0},", a.GetValue(i));
     string retVal = sb.ToString();
     return retVal.Substring(0, retVal.Length - 1);
    }
    

    Then, I would recommend you skip trying to parameterize the command given that this is an array of ints and just use:

    command.CommandText = @"SELECT id,
                startDateTime, endDateTime From
                tb_bookings WHERE buildingID IN
                (" + SQLArrayToInString(buildingIDs) + ") AND startDateTime <=
                @fromDate";
    
    0 讨论(0)
提交回复
热议问题