OleDbCommandBuilder 更新 - 至少缺少一个参数值
OleDbCommandBuilder Update - at least one parameter values are missing
我做了什么:
我正在使用 OleDbAdapter 从数据库中读取数据,填充一个新的 DataTable。这很顺利。然后我想在该 DataTable 中添加一列,这也很顺利。
我添加了一个 OleDbCommandBuilder,以使用多一列的 DataTable 更新数据库。我用 OleDbCommandBuilder 的 'automatical way' 进行了尝试,因为我认为我想要的很简单。但到目前为止,这还没有奏效。
我期待的
是 OleDbCommandBuilder 正在为我编写一个新的 SQL 命令,其中包含 'UPDATE' 或 'INSERT'。我进一步预计,我无法读取 OleDbAdapter 中的所有命令,SELECT 命令除外,因为 OleDbAdapter 在使用它们之前从构建器获取命令。
我在互联网上看到,如果我调用 adapter.Update(...),则不需要 adapter.Fill(...)。但是没有 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) adapter, builder ... 的顺序是否正确?
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;
}
您通过向数据添加新列修改了 DataTable 的结构table,这没有反映在生成的 update/insert/delete sql 命令中。
看看这个例子:OleDbCommandBuilder Class
如此简单:
adapter.Update(table);
仅更新服务器中table库中的数据(如果更改)
1) Do I expect something wrong?
不,它在工作,但在 MS access 中 table 的基础结构没有变化
2) Which parameter hasn't got a value?
你没有在 SQL 命令中传递参数
3) Are the adapter, builder ... placed in the right order?
是的,但删除了修改数据的部分table。没有效果
4) Have I got something additional to do, like calling a function to update the SQL command withing the adapter?
查看我的代码和评论。
5) How can I improve the way I solve that problem? E.g.: Is there any event which will help me to understand more what is going on? How to catch such an event?
您不能通过添加新列
来修改数据的结构table
更新
我测试了你的代码,修改了注释:
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;
}
更新2:
如果您有兴趣向 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 测试了代码,它工作正常。
我做了什么: 我正在使用 OleDbAdapter 从数据库中读取数据,填充一个新的 DataTable。这很顺利。然后我想在该 DataTable 中添加一列,这也很顺利。
我添加了一个 OleDbCommandBuilder,以使用多一列的 DataTable 更新数据库。我用 OleDbCommandBuilder 的 'automatical way' 进行了尝试,因为我认为我想要的很简单。但到目前为止,这还没有奏效。
我期待的 是 OleDbCommandBuilder 正在为我编写一个新的 SQL 命令,其中包含 'UPDATE' 或 'INSERT'。我进一步预计,我无法读取 OleDbAdapter 中的所有命令,SELECT 命令除外,因为 OleDbAdapter 在使用它们之前从构建器获取命令。
我在互联网上看到,如果我调用 adapter.Update(...),则不需要 adapter.Fill(...)。但是没有 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) adapter, builder ... 的顺序是否正确?
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;
}
您通过向数据添加新列修改了 DataTable 的结构table,这没有反映在生成的 update/insert/delete sql 命令中。
看看这个例子:OleDbCommandBuilder Class
如此简单:
adapter.Update(table);
仅更新服务器中table库中的数据(如果更改)
1) Do I expect something wrong?
不,它在工作,但在 MS access 中 table 的基础结构没有变化
2) Which parameter hasn't got a value?
你没有在 SQL 命令中传递参数
3) Are the adapter, builder ... placed in the right order?
是的,但删除了修改数据的部分table。没有效果
4) Have I got something additional to do, like calling a function to update the SQL command withing the adapter?
查看我的代码和评论。
5) How can I improve the way I solve that problem? E.g.: Is there any event which will help me to understand more what is going on? How to catch such an event?
您不能通过添加新列
来修改数据的结构table更新
我测试了你的代码,修改了注释:
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;
}
更新2:
如果您有兴趣向 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 测试了代码,它工作正常。