Pau*_*i73 1 c# sql oledb syntax-error
我正在尝试将新行添加到 C# 中现有的 MS Access 数据库表中。但是,当我调用 DataAdapter\xe2\x80\x99s Update 方法时,我在 INSERT INTO 语句\xe2\x80\x9d 中收到 \xe2\x80\x9c 语法错误。我的代码是:
\n\ntry\n{\n // Open the database \n OleDbCommand mySelectCommand = new OleDbCommand(strAccessSelect, myAccessConn);\n OleDbDataAdapter myDataAdapter = new OleDbDataAdapter(mySelectCommand);\n OleDbCommandBuilder myCommandBuilder = new OleDbCommandBuilder(myDataAdapter);\n myAccessConn.Open();\n\n // Get Analogue table\n int rowCount = myDataAdapter.Fill(myDataSet, "Analogue");\n Console.WriteLine("Row Count: " + rowCount);\n DataTable analogues = myDataSet.Tables["Analogue"];\n analogues.PrimaryKey = new DataColumn[] { analogues.Columns["Name"] };\n\n // Create a new row.\n System.Data.DataRow newRow;\n newRow = analogues.NewRow();\n newRow["Name"] = "My new row";\n newRow["Area"] = "System";\n newRow["Description"] = "My new row, created by me!";\n\n analogues.Rows.Add(newRow);\n myDataAdapter.InsertCommand = myCommandBuilder.GetInsertCommand();\n myDataAdapter.UpdateCommand = myCommandBuilder.GetUpdateCommand();\n Console.WriteLine("Insert Command: " + myDataAdapter.InsertCommand.ToString());\n Console.WriteLine("Update Command: " + myDataAdapter.UpdateCommand.ToString());\n\n myDataAdapter.Update(myDataSet, "Analogue");\n}\ncatch (Exception ex)\n{\n Console.WriteLine("Error: Failed to manipulate the DataBase.\\n{0}", ex.ToString());\n return;\n}\nfinally\n{\n myAccessConn.Close();\n}\nRun Code Online (Sandbox Code Playgroud)\n\n为了简洁起见,我从表中删除了大部分列,但所有列标题都用引号引起来,它们都不包含任何空格,也没有保留字。我删除的都不是 Access 关键字,但我注意到 \xe2\x80\x9cNAME\xe2\x80\x9d 和 \xe2\x80\x9cDescription\xe2\x80\x9d 是。我不\xe2\x80\x99t 相信这导致了我的问题,因为我已经能够修改现有行中 \xe2\x80\x9cDescription\xe2\x80\x9d 列中的文本。
\n\n命令生成器正在为我生成以下内容,这看起来不太正确:
\n\nSystem.Data.OleDb.OleDbCommand\nRun Code Online (Sandbox Code Playgroud)\n\n我需要手动构建这个命令吗?如果是这样,我应该使用哪个,插入或更新 \xe2\x80\x93 适配器只有一个更新方法,据我了解可以调用更新或插入?
\n\n这是有错误的堆栈跟踪:
\n\nSystem.Data.OleDb.OleDbException (0x80040E14): Syntax error in INSERT INTO statement.\n at System.Data.Common.DbDataAdapter.UpdatedRowStatusErrors(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount)\n at System.Data.Common.DbDataAdapter.UpdatedRowStatus(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount)\n at System.Data.Common.DbDataAdapter.Update(DataRow[] dataRows, DataTableMapping tableMapping)\n at System.Data.Common.DbDataAdapter.UpdateFromDataTable(DataTable dataTable, DataTableMapping tableMapping)\n at System.Data.Common.DbDataAdapter.Update(DataSet dataSet, String srcTable)\n at SystemMonitor.MainWindow.mnuGenerateSMACS6Interface_Click(Object sender, EventArgs e) in c:\\iogen\\code\\MainWindow.cs:line 436\nRun Code Online (Sandbox Code Playgroud)\n
如果您SelectCommand.CommandText有一个SELECT * FROM Analogue,那么InsertCommand由 构建的OleDbCommandBuilder每列都包含一个 INSERT 列。
如果您想从 INSERT 中删除某些列,那么您需要自己构建命令。
但是,语法错误的根源是 Access 2007 中存在保留字,例如名称和描述。施梅尔特先生已经在其评论中指出,解决方案很简单。
OleDbCommandBuilder myCommandBuilder = new OleDbCommandBuilder(myDataAdapter);
myCommandBuilder.QuotePrefix = "[";
myCommandBuilder.QuoteSuffix = "]";
Run Code Online (Sandbox Code Playgroud)
这将强制 OleDbCommandBuilder 在列名和表名周围使用适当的前缀和后缀来构造用于插入和更新的 CommandText,从而产生类似的 CommandText
"INSERT INTO [Analogue] ([Name], [Area], [Description], ...) VALUES(?, ?, ?, ...)"
Run Code Online (Sandbox Code Playgroud)
DataAdapter.UpdateCommand 执行 INSERT/UPDATE/DELETE 命令,查看DataTable 中已更改的行的DataRow.RowState属性