Pass Array Parameter in SqlCommand

前端 未结 12 1889
情深已故
情深已故 2020-11-22 08:27

I am trying to pass array parameter to SQL commnd in C# like below, but it does not work. Does anyone meet it before?

string sqlCommand = \"SELECT * from Ta         


        
相关标签:
12条回答
  • 2020-11-22 09:05

    If you are using MS SQL Server 2008 and above you can use table-valued parameters like described here http://www.sommarskog.se/arrays-in-sql-2008.html.

    1. Create a table type for each parameter type you will be using

    The following command creates a table type for integers:

    create type int32_id_list as table (id int not null primary key)
    

    2. Implement helper methods

    public static SqlCommand AddParameter<T>(this SqlCommand command, string name, IEnumerable<T> ids)
    {
      var parameter = command.CreateParameter();      
    
      parameter.ParameterName = name;
      parameter.TypeName = typeof(T).Name.ToLowerInvariant() + "_id_list";
      parameter.SqlDbType = SqlDbType.Structured;
      parameter.Direction = ParameterDirection.Input;
    
      parameter.Value = CreateIdList(ids);
    
      command.Parameters.Add(parameter);
      return command;
    }
    
    private static DataTable CreateIdList<T>(IEnumerable<T> ids)
    {
      var table = new DataTable();
      table.Columns.Add("id", typeof (T));
    
      foreach (var id in ids)
      {
        table.Rows.Add(id);
      }
    
      return table;
    }
    

    3. Use it like this

    cmd.CommandText = "select * from TableA where Age in (select id from @age)"; 
    cmd.AddParameter("@age", new [] {1,2,3,4,5});
    
    0 讨论(0)
  • 2020-11-22 09:05

    Since there is a method on

    SqlCommand.Parameters.AddWithValue(parameterName, value)
    

    it might be more convenient to create a method accepting a parameter (name) to replace and a list of values. It is not on the Parameters level (like AddWithValue) but on command itself so it's better to call it AddParametersWithValues and not just AddWithValues:

    query:

    SELECT * from TableA WHERE Age IN (@age)
    

    usage:

    sqlCommand.AddParametersWithValues("@age", 1, 2, 3);
    

    the extension method:

    public static class SqlCommandExtensions
    {
        public static void AddParametersWithValues<T>(this SqlCommand cmd,  string parameterName, params T[] values)
        {
            var parameterNames = new List<string>();
            for(int i = 0; i < values.Count(); i++)
            {
                var paramName = @"@param" + i;
                cmd.Parameters.AddWithValue(paramName, values.ElementAt(i));
                parameterNames.Add(paramName);
            }
    
            cmd.CommandText = cmd.CommandText.Replace(parameterName, string.Join(",", parameterNames));
        }
    }
    
    0 讨论(0)
  • 2020-11-22 09:10

    try

    sqlComm.Parameters["@Age"].Value = sb.ToString().Replace(","," ");
    
    0 讨论(0)
  • 2020-11-22 09:15

    I want to propose another way, how to solve limitation with IN operator.

    For example we have following query

    select *
    from Users U
    WHERE U.ID in (@ids)
    

    We want to pass several IDs to filter users. Unfortunately it is not possible to do with C# in easy way. But I have fount workaround for this by using "string_split" function. We need to rewrite a bit our query to following.

    declare @ids nvarchar(max) = '1,2,3'
    
    SELECT *
    FROM Users as U
    CROSS APPLY string_split(@ids, ',') as UIDS
    WHERE U.ID = UIDS.value
    

    Now we can easily pass one parameter enumeration of values separated by comma.

    0 讨论(0)
  • 2020-11-22 09:15

    Overview: Use the DbType to set the parameter type.

    var parameter = new SqlParameter();
    parameter.ParameterName = "@UserID";
    parameter.DbType = DbType.Int32;
    parameter.Value = userID.ToString();
    
    var command = conn.CreateCommand()
    command.Parameters.Add(parameter);
    var reader = await command.ExecuteReaderAsync()
    
    0 讨论(0)
  • 2020-11-22 09:15

    Use .AddWithValue(), So:

    sqlComm.Parameters.AddWithValue("@Age", sb.ToString().TrimEnd(','));

    Alternatively, you could use this:

    sqlComm.Parameters.Add(
        new SqlParameter("@Age", sb.ToString().TrimEnd(',')) { SqlDbType = SqlDbType. NVarChar }
        );
    

    Your total code sample will look at follows then:

    string sqlCommand = "SELECT * from TableA WHERE Age IN (@Age)";
    SqlConnection sqlCon = new SqlConnection(connectString);
    SqlCommand sqlComm = new SqlCommand();
    sqlComm.Connection = sqlCon;
    sqlComm.CommandType = System.Data.CommandType.Text;
    sqlComm.CommandText = sqlCommand;
    sqlComm.CommandTimeout = 300;
    
    StringBuilder sb = new StringBuilder();
    foreach (ListItem item in ddlAge.Items)
    {
         if (item.Selected)
         {
             sb.Append(item.Text + ",");
         }
    }
    
    sqlComm.Parameters.AddWithValue("@Age", sb.ToString().TrimEnd(','));
    
    // OR
    
    // sqlComm.Parameters.Add(new SqlParameter("@Age", sb.ToString().TrimEnd(',')) { SqlDbType = SqlDbType. NVarChar });
    
    0 讨论(0)
提交回复
热议问题