OleDbCommandBuilder更新-至少缺少一个参数值

时间:2018-08-20 13:29:56

标签: c# sql .net oledbcommand oledbdataadapter

我做什么: 我正在使用OleDbAdapter从数据库中读取数据,并填充了一个新的DataTable。一切顺利然后,我想在该DataTable中添加一列,这也很好。

我添加了一个OleDbCommandBuilder,以使用具有更多列的DataTable更新数据库。我以OleDbCommandBuilder的“自动方式”进行了尝试,因为我认为我想要的很简单。但是到目前为止,这没有用。

我期望的结果 是OleDbCommandBuilder正在为我编写一个新的SQL命令,其中包含“ UPDATE”或“ INSERT”。我进一步期望,除了SELECT命令之外,我无法读取OleDbAdapter中的所有命令,因为OleDbAdapter会在使用它们之前直接从构建器获取命令。

我已经在互联网上阅读过该适配器。如果我打电话给adapter.Update(...),则不需要填充(...)。但是没有adapter.Fill(...),我不会从数据库中获取内容。

最后一个问题有了名字:

现在,在查找问题之后,我收到以下消息:System.Data.OleDbException:对于至少一个参数,没有给出任何值。

我的问题:

1)我期望发生什么问题吗?

2)哪个参数没有值? 已解决,这有助于我了解: https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.parameters?redirectedfrom=MSDN&view=netframework-4.7.2#System_Data_SqlClient_SqlCommand_Parameters

3)适配器,构建器...的放置顺序是否正确?

4)我还有其他事情要做吗,例如使用适配器调用函数来更新SQL命令?

5)如何改善解决该问题的方式?例如:是否有任何事件可以帮助我了解更多情况?如何捕捉这样的事件?

非常感谢!

这是我的代码-最初它分为两个功能。但我为您合而为一:

  public virtual bool AddColumnOfString_ToDataTable(string tableName, string newColumnName, string defaultCellValue)
    {
       /// Approach: Accessing database at minimum time.
       ///    returns true if  column name could not be found and column could be added

        DataTable table = new DataTable();
        string strSQL = "SELECT " + tableName;
        OleDbDataAdapter adapter = new OleDbDataAdapter(strSQL, strConnection);
        adapter.Fill(table);     
        OleDbCommandBuilder builder = new OleDbCommandBuilder(adapter);

        bool result = false;

        if (false == HasColumn(newColumnName))
        {
            DataColumn newColumn = new DataColumn(newColumnName, typeof(System.String));
            newColumn.DefaultValue = defaultCellValue;
            table.Columns.Add(newColumn);
            result = true;
        }

        adapter.Update(table);

        return result;
    }

1 个答案:

答案 0 :(得分:1)

您通过向数据表中添加newcolumn来修改了DataTable的结构,这在生成的update / insert / delete sql命令中没有得到体现。

看看这个例子:OleDbCommandBuilder Class

很简单:

   adapter.Update(table);

仅更新服务器中基表中的数据(如果已更改)

  

1)我期望发生什么问题吗?

不,它可以正常工作,但是MS Access中的基表结构没有变化

  

2)哪个参数没有值?

您没有在SQL命令中传递参数

  

3)适配器,构建器...的放置顺序是否正确?

是,但是删除修改数据表的部分。没有效果

  

4)我还有其他事情要做吗,例如使用适配器调用函数来更新SQL命令?

用注释查看我的代码。

  

5)如何改善解决该问题的方式?例如:是否有任何事件可以帮助我了解更多情况?如何捕捉这样的事件?

您无法通过添加新列来修改数据表的结构

更新

我测试您的代码,并用注释对其进行修改:

       public  bool AddColumnOfString_ToDataTable(string tableName, string newColumnName, string defaultCellValue)
            {
                // Approach: Accessing database at minimum time.
                //    returns true if  column name could not be found and column could be added

                DataTable table = new DataTable();


                //string strSQL = "SELECT " + tableName; // not valid syntax
                string strSQL = "SELECT * from " + tableName;
                OleDbDataAdapter adapter = new OleDbDataAdapter(strSQL, myConnectionString);
                adapter.Fill(table);
                OleDbCommandBuilder builder = new OleDbCommandBuilder(adapter);

                bool result = false;
                // remove this code, it has no effect on the underlying base table in MS Access databas
                //any change in the structure of datatable has no effect on the database

                /*
                if (false == table.HasColumn(newColumnName))
                {
                    DataColumn newColumn = new DataColumn(newColumnName, typeof(System.String));
                    newColumn.DefaultValue = defaultCellValue;
                    table.Columns.Add(newColumn);
                    result = true;
                }
                */

                //  code to modify data in DataTable here

                //Without the OleDbCommandBuilder this line would fail
                adapter.Update(table);

                //just to review the generated code                 
                Console.WriteLine(builder.GetUpdateCommand().CommandText);
                Console.WriteLine(builder.GetInsertCommand().CommandText);
                return result;
            }

Update2:

如果您有兴趣向MS Access数据库添加新列,则可以运行以下代码:

 public   bool AddColumn(OleDbConnection con, 
                string tableName,string colName,string colType, object defaultValue)
            {
                string query = $"ALTER TABLE {tableName}  ADD COLUMN {colName} {colType} DEFAULT {defaultValue} ";
                var cmd = new OleDbCommand(query, con);
                try
                {
                    con.Open();
                    cmd.ExecuteNonQuery();
                    Console.WriteLine("Sql Executed Successfully");
                    return true;
                }
                catch (OleDbException e)
                {
                    Console.WriteLine("Error Details: " + e);
                }
                finally
                {
                    Console.WriteLine("closing conn");
                    con.Close();
                }
                return false;
            }

      public   void AddColumnTest()
            {
                OleDbConnection con = new OleDbConnection(myConnectionString);
                string tableName="table1";
                string colName="country";
                string colType="text (30)";
                object defaultValue = "USA";
                AddColumn(con, tableName, colName, colType, defaultValue);
            }               

我使用MS Access测试了代码,并且工作正常。