Question

I am trying to add a new row into an existing MS Access database table in C#. However, when I make the call to the DataAdapter’s Update method I get a “Syntax error in INSERT INTO statement”. My code is:

try
{
    // Open the database 
    OleDbCommand mySelectCommand = new OleDbCommand(strAccessSelect, myAccessConn);
    OleDbDataAdapter myDataAdapter = new OleDbDataAdapter(mySelectCommand);
    OleDbCommandBuilder myCommandBuilder = new OleDbCommandBuilder(myDataAdapter);
    myAccessConn.Open();

    // Get Analogue table
    int rowCount = myDataAdapter.Fill(myDataSet, "Analogue");
    Console.WriteLine("Row Count: " + rowCount);
    DataTable analogues = myDataSet.Tables["Analogue"];
    analogues.PrimaryKey = new DataColumn[] { analogues.Columns["Name"] };

    // Create a new row.
    System.Data.DataRow newRow;
    newRow = analogues.NewRow();
    newRow["Name"] = "My new row";
    newRow["Area"] = "System";
    newRow["Description"] = "My new row, created by me!";

    analogues.Rows.Add(newRow);
    myDataAdapter.InsertCommand = myCommandBuilder.GetInsertCommand();
    myDataAdapter.UpdateCommand = myCommandBuilder.GetUpdateCommand();
    Console.WriteLine("Insert Command: " + myDataAdapter.InsertCommand.ToString());
    Console.WriteLine("Update Command: " + myDataAdapter.UpdateCommand.ToString());

    myDataAdapter.Update(myDataSet, "Analogue");
}
catch (Exception ex)
{
    Console.WriteLine("Error: Failed to manipulate the DataBase.\n{0}", ex.ToString());
    return;
}
finally
{
    myAccessConn.Close();
}

I have removed most of the columns from the table for brevity, but all of the column headers are in quotes, none of them contain any spaces and none are reserved words. None of the ones I have removed are Access keywords, but I note that “NAME” and “Description” are. I don’t believe this is causing my problem because I have been able to modify the text in the “Description” column in an existing row.

The Command Builder is generating the following for me which doesn’t seem quite right:

System.Data.OleDb.OleDbCommand

Do I need to build this command manually? If so, which should I use, the Insert or the Update – the Adapter only has an Update method which as I understand can call either the Update or the Insert?

Here is the stack trace with the error:

System.Data.OleDb.OleDbException (0x80040E14): Syntax error in INSERT INTO statement.
   at System.Data.Common.DbDataAdapter.UpdatedRowStatusErrors(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount)
   at System.Data.Common.DbDataAdapter.UpdatedRowStatus(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount)
   at System.Data.Common.DbDataAdapter.Update(DataRow[] dataRows, DataTableMapping tableMapping)
   at System.Data.Common.DbDataAdapter.UpdateFromDataTable(DataTable dataTable, DataTableMapping tableMapping)
   at System.Data.Common.DbDataAdapter.Update(DataSet dataSet, String srcTable)
   at SystemMonitor.MainWindow.mnuGenerateSMACS6Interface_Click(Object sender, EventArgs e) in c:\iogen\code\MainWindow.cs:line 436
Was it helpful?

Solution

If, in your SelectCommand.CommandText you have a SELECT * FROM Analogue, then the InsertCommand built by the OleDbCommandBuilder contains an INSERT column for every column.
If you want to remove some columns from the INSERT then you need to build the command by yourself.

However, the origin of the Syntax Error, is the presence of reserved words in Access 2007 like NAME and DESCRIPTION. The solution is simple, Mr Schmelter has already pointed in its comment.

OleDbCommandBuilder myCommandBuilder = new OleDbCommandBuilder(myDataAdapter);
myCommandBuilder.QuotePrefix = "[";
myCommandBuilder.QuoteSuffix = "]";

This will force the OleDbCommandBuilder to construct the CommandText for insert and update using the appropriate Prefix and Suffix around the column names and table names resulting in a CommandText like

"INSERT INTO [Analogue] ([Name], [Area], [Description], ...) VALUES(?, ?, ?, ...)" 

The DataAdapter.UpdateCommand executes both INSERT/UPDATE/DELETE commands looking at the DataRow.RowState property of the row in the DataTable that has been changed

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top