Search code examples
c#oracle

Why am I getting a constraint violation on DataAdapter update?


I'm maintaining a WCF service which uses the following to update a bunch of records from a desktop client.

OracleTransaction transaction = conn.BeginTransaction(IsolationLevel.ReadCommitted);
OracleCommand cmd = conn.CreateCommand();
cmd.Transaction = transaction;
cmd.CommandText = "SELECT ..."; // elided
OracleDataAdapter odaProjectFields = new OracleDataAdapter(cmd);
OracleCommandBuilder ocBuilder = new OracleCommandBuilder(odaProjectFields);
odaProjectFields.MissingSchemaAction = MissingSchemaAction.AddWithKey;

try
{
    updatedRows = odaProjectFields.Update(dtFields);
    transaction.Commit();
}
catch (Exception)
{
    transaction.Rollback();
    throw;
}

dtFields comes in from the client and is a DataTable with the updated rows. Every row is already in the table, and every row's RowState is Modified, so I'd assume the OracleDataAdapter should be issuing update statements. But for whatever reason, I'm getting unique constraint violations. (ORA-00001, with the name of the table's primary key).

If I copy and paste the original data into a text editor and use find and replace to generate a bunch of update statements, it works just fine.

What's going on? Is it possible to "peer in" to see what the adapter is trying to do?


Solution

  • A DataAdapter has two events that you can use to see what's happening and what is the command that fails.

    RowUpdating
    RowUpdated
    

    For example

    odaProjectFields.RowUpdating += onUpdating;
    ....
    
    
    void onUpdating(object sender, OleDbRowUpdatingEventArgs e)
    {
        // Here you can check:
        Console.WriteLine(e.Command.CommandText);
        foreach(var p in e.Command.Parameters)
            Console.WriteLine($"Param Name={p.ParameterName} => Value={p.Value}";
    }
    

    Running this code should give you an hint to find on which row the problem happens