Passing a SQL parameter to an IN() clause using typed datasets in .NET

后端 未结 8 1790
别跟我提以往
别跟我提以往 2020-11-28 10:31

First apologies as there are similar questions on this site, but none of them answer this problem directly.

Im using typed datasets in VS 2010. I create a TableAdapt

相关标签:
8条回答
  • 2020-11-28 11:10

    @Joe is right.

    Or you can use foreach loop to do that.

    Something like:

       int[] arr = new int[3]; 
        arr[0] = "1";        
        arr[1] = "2";             
        arr[2] = "3";             
    
    foreach(vat data in arr)
    {
    
    //Do your Code here
    
    // 
    var MyDatatable = obj.GetDatabyID(data);
    
    TableAdapter.Fill(MyDataTable);
    
    }
    

    Regards

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

    I was able to solve this by setting the ClearBeforeFill property to to false and filling the TableAdapter in a foreach loop.

    List<string> aList = new List<string>();
    aList.Add("1");
    aList.Add("2");
    aList.Add("3");
    
    yourTableAdapter.ClearBeforeFill = true;
    yourTableAdapter.Fill(yourDataSet.yourTableName, ""); //clears table
    
    foreach (string a in aList)
    {
        yourTableAdapter.ClearBeforeFill = false;
        yourTableAdapter.Fill(yourDataSet.yourTableName, a);
    }
    yourTableAdapter.Dispose();
    
    0 讨论(0)
  • 2020-11-28 11:11

    SQL Server 2008 has a feature called Table-Valued Parameters

    So you need to

    1. define your query as SELECT * from Table WHERE ID IN (SELECT * FROM (@IDs))
    2. go back in the TableAdapter visual designer in Visual Studio, and update the @IDS parameter to modify the @IDS parameter as DbType=Object and ProviderType=Structured
    3. run this SQL batch in the database your are using: CREATE TYPE MyIntArray AS TABLE ( Value INT );GO. This will create a MyIntArray "table type" with just one column of INT type.
    4. Now the tricky thing is to pass the "MyIntArray" type to the TableAdapter, on the ADO.NET side.

    Unfortunately the Table Adapter designer does not support the SqlParameter.TypeName argument, so we need to fix it by ourselves. The goal is to modify the CommandCollection property of the generated TableAdapter class. Unfortunately, this property is protected, so you have to derive the TableAdapter or for example use Reflection to tweak it. Here is an example with a derived class:

        public class MyTableAdapter2 : MyTableAdapter
        {
            public MyTableAdapter2()
            {
                SqlCommand[] cmds = base.CommandCollection;
                // here, the IDS parameter is index 0 of command 1
                // you'll have to be more clever, but you get the idea
                cmds[1].Parameters[0].TypeName = "MyIntArray";
            }
        }
    

    And this is how you can call this method:

            MyTableAdapter t = new MyTableAdapter2();
    
            // create the TVP parameter, with one column. the name is irrelevant.
            DataTable tvp = new DataTable();
            tvp.Columns.Add();
    
            // add one row for each value
            DataRow row = tvp.NewRow();
            row[0] = 1;
            tvp.Rows.Add(row);
    
            row = tvp.NewRow();
            row[0] = 2;
            tvp.Rows.Add(row);
    
            row = tvp.NewRow();
            row[0] = 3;
            tvp.Rows.Add(row);
    
            t.Fill(new MyDataTable(), tvp);
    
    0 讨论(0)
  • 2020-11-28 11:16

    You also can create a list of IDs parameters so instead of using @IDs you will use @ID1, @ID2, @ID3, etc

    var sql = "SELECT * from Table WHERE ID IN (" + getKeys(values.Count) + ")";
    

    And getKeys(count) do something like this:

    var result = string.Empty;
                for (int i = 0; i < count; i++)
                {
                    result += ", @ID" + i;
                }
                return string.IsNullOrEmpty(result) ? string.Empty : result.Substring(1);
    

    and Finally, add the parameters:

    foreach (int i = 0; i < values.Count; i++)
                {
                    cmd.Parameters.Add(new SqlParameter("@ID" + i, SqlDbType.VarChar) { Value = values[i]});
                }
    
    0 讨论(0)
  • 2020-11-28 11:24

    You can't use a single parameter for a list of values in this way. But there may be database-specific ways to achieve what you want. For example, with SQL Server 2005 or later you could create a table-valued function to split your string parameter, something like:

    CREATE FUNCTION dbo.F_Split
    (
    @InputString VARCHAR(MAX)
    ,@Separator VARCHAR(MAX)
    )
    RETURNS @ValueTable TABLE (Value VARCHAR(MAX))
    AS
    BEGIN
    
        DECLARE @SeparatorIndex INT, @TotalLength INT, @StartIndex INT, @Value VARCHAR(MAX)
        SET @TotalLength=LEN(@InputString)
        SET @StartIndex = 1
    
        IF @Separator IS NULL RETURN
    
        WHILE @StartIndex <= @TotalLength
        BEGIN
            SET @SeparatorIndex = CHARINDEX(@Separator, @InputString, @StartIndex)
            IF @SeparatorIndex > 0
            BEGIN
                SET @Value = SUBSTRING(@InputString, @StartIndex, @SeparatorIndex-@StartIndex)
                SET @StartIndex = @SeparatorIndex + 1
            END
            ELSE
            BEGIN
                Set @Value = SUBSTRING(@InputString, @StartIndex, @TotalLength-@StartIndex+1)
                SET @StartIndex = @TotalLength+1
            END
            INSERT INTO @ValueTable
            (Value)
            VALUES
            (@Value)
        END
    
        RETURN
    END
    

    You would then use it as follows:

    SELECT * from Table WHERE ID IN (SELECT CAST(Value AS INT) FROM F_Split(@IDs, ','))
    
    0 讨论(0)
  • 2020-11-28 11:24

    I tried a workaround for using string "contains" concept in SQL way:

    In your case, change the SQL -

    Original:

    SELECT * from Table WHERE ID IN(@IDs)

    Become:

    SELECT * from Table WHERE CharIndex(','+Cast(ID As Varchar(10))+',',@IDs) > 0

    With .net code -

    Original:

    TableAdapter.Fill(MyDataTable,"1,2,3")

    Become:

    TableAdapter.Fill(MyDataTable,",1,2,3,")

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