Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inserting multiple rows with DB2Command.ExecuteNonQuery

I'm attempting to insert multiple rows into a DB2 database using C# code like this:

string query = 
"INSERT INTO TESTDB2.RG_Table (V,E,L,N,Q,B,S,P) values" +
"('abc', 'def', '2009-03-27 12:01:19', 'ghi', 'jkl', NULL, NULL, NULL)," +
"('abc', 'def', '2009-03-27 12:01:19', 'ghi', 'jkl', NULL, NULL, NULL)";

DB2Command cmd = new DB2Command(query, this.connection, this.transaction);

cmd.ExecuteNonQuery();

If I stop building the query string after the first set of values, it executes without an error. Attempting to load multiple values using this method results in the following error:

Upload error : ERROR [42601] [IBM][DB2] SQL0104N  
An unexpected token "," was found following "".  
Expected tokens may include:  "<END-OF-STATEMENT>".  SQLSTATE=42601

The SQL syntax matches that which I have read elsewhere and IBM's documentation gives this example:

cmd = conn.CreateCommand();
cmd.Transaction = trans;

cmd.CommandText =
"INSERT INTO company_a VALUES(5275, 'Sanders', 20, 'Mgr', 15, 18357.50), " +
"(5265, 'Pernal', 20, 'Sales', NULL, 18171.25), " +
"(5791, 'O''Brien', 38, 'Sales', 9, 18006.00)";

cmd.ExecuteNonQuery();

Can anyone explain what could account for this?


1 Answers

I realize this is a really old question, but so far none of the answers have gotten to the real root of the problem. Since he can't use multiple VALUES clauses, I'm going to guess he's on z/OS, which doesn't support that. See my other answer here for more information.

There is an alternative, though, since he appears to be using .NET, which is the "Chaining" ability of the driver. This allows you to batch up multiple inserts/updates/deletes, and when you "end" your chain, the driver sends all of the statements at once. Here's some example code:

<!-- language: lang-cs --> //Code parser seems to be going crazy here...
public void InsertToDatabase(IEnumerable<Row> rows)
{
    using (var conn = new DB2Connection())
    using (var trans = conn.BeginTransaction())
    using (var cmd = conn.CreateCommand())
    {
        cmd.Transaction = trans;
        cmd.CommandText =
            "INSERT INTO company_a VALUES " +
            "(@field1,@field2,@field3,@field4,@field5,@field6)";

        conn.BeginChain();
        foreach (var row in rows)
        {
            cmd.Parameters.Clear();
            cmd.Parameters.Add("@field1", row.Field1);
            cmd.Parameters.Add("@field2", row.Field2);
            cmd.Parameters.Add("@field3", row.Field3);
            cmd.Parameters.Add("@field4", row.Field4);
            cmd.Parameters.Add("@field5", row.Field5);
            cmd.Parameters.Add("@field6", row.Field6);
            cmd.ExecuteNonQuery();
        }
        conn.EndChain();
        trans.Commit();
    }
}

If DB2 throws any exceptions, you will only get it when you run EndChain, and they will all come at once.

like image 176
bhamby Avatar answered May 19 '26 14:05

bhamby



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!