2

I want to create a multi-line insert statement along these lines:

insert into foo (
    value1,
    value2,
    value3
) values 
( "1", "2", "3"),
( "4", "5", "6"),
( "7", "8", "9");

where the number of rows to be inserted is variable. Is there a way to construct this query using IDBCommand parameterization?

Jeremy Holovacs
  • 22,480
  • 33
  • 117
  • 254

2 Answers2

1

Something like this should work fine.

IDbCommand cmd = new SqlCommand();
StringBuilder sb = new StringBuilder();
sb.Append("insert into foo(col, col2, col3), values");
int parms = 0;

for(int i = 0 ; i<3; i++)
{
    sb.AppendFormat("( @{0}, @{1}, @{2}),", parms, parms + 1, parms + 2);
    cmd.Parameters.Add(new SqlParameter((parms++).ToString(), ""));
    cmd.Parameters.Add(new SqlParameter((parms++).ToString(), ""));
    cmd.Parameters.Add(new SqlParameter((parms++).ToString(), ""));
}
sb.Append(";");
cmd.Parameters;
cmd.CommandText = sb.ToString().Replace(",;", ";");
iamkrillin
  • 6,798
  • 1
  • 24
  • 51
0

There is, to my knowledge, no way to supply a variable number of parameters to an IDbCommand at once. You can create the IDbCommand once and reuse it for each set of parameter values though:

using (IDbCommand command = myConn.CreateCommand())
{
    command.CommandText = "insert into foo (value1, value2, value3) values (@v1, @v2, @v3)";
    IDbDataParameter param1 = command.CreateParameter() { ParameterName = "@v1" };
    // param2, param3
    foreach (string[] row in records)
    {
        param1.Value = row[0];
        // param2, param3
        command.ExecuteNonQuery();
    }
}

Especially within a transaction this should fast if performance was your concern. See this thread for a discussion on performance of one big concatenated insert vs. multiple ExecuteNonQuerys in a transaction.

C.Evenhuis
  • 25,996
  • 2
  • 58
  • 72