我有一种通过OleDb连接更新MS Access数据库的现有方法。我已经使用此方法更新过去的数据,但我现在有一个类型不匹配错误,我已经在图像字段中添加到访问表(OLE对象存储为长二进制数据) )。为了从访问数据库中检索数据,我从OleDbdataAdapter标准填充DataTable。我可以从数据库中提取图像并使其显示完美,因此我知道它已正确存储。
为了将DataTable中的值更新到文件数据库中,我从DataTable字段动态构建更新命令,并包含每个字段的参数。要将字段类型从系统类型映射到OleDbType,我使用一个返回所需类型的简单switch方法。
一切都按照它应该的方式工作,除非我想从DataTable中的特定行清除图像字段,然后更新数据库。 DataTable显示正确的空值,但是当调用update命令时,它会抛出此错误。我尝试将字段的值设置为string.empty,null和DbNull.Value,但都无济于事。
我是否必须以SQL' DELETE FROM'?的格式创建一个完全独立的方法?看起来这首先会破坏将它与DataTable联系起来的目的,但我当然没有权威这个主题。提前感谢任何建议。
以下是我用作参考的方法:
更新Db表:
public static bool UpdateDbTable(string dbPath, string rowFilter, DataTable inputTable)
{
// Create the connection
using (var connection = GetConnection(dbPath))
{
try
{
// Open the connection
connection.Open();
// Create the update command
var updateCommand = GetUpdateCommand(inputTable, rowFilter, connection);
// Link the new data adapter
var adapter = new OleDbDataAdapter { UpdateCommand = updateCommand };
// Update the MDB table
adapter.Update(inputTable);
} // Return false on error
catch (OleDbException)
{
return false;
}
}
// Return true on success
return true;
}
构建更新命令:
private static OleDbCommand GetUpdateCommand(DataTable inputTable, string rowFilter, OleDbConnection connection)
{
// Create the return command
var retCommand = connection.CreateCommand();
// Build the command string
var sb = new StringBuilder(string.Format("UPDATE {0} SET ", inputTable.TableName));
foreach (DataColumn col in inputTable.Columns)
{
// Append the command text
sb.AppendFormat("{0} = ?, ", col.ColumnName);
// Create the column parameter
var par = new OleDbParameter
{
ParameterName = col.ColumnName,
OleDbType = GetOleDbType(col.DataType),
Size = col.MaxLength,
SourceColumn = col.ColumnName
};
// Set any null values to DBNull
if (par.Value == null) par.Value = DBNull.Value;
// Add the parameter to the return command
retCommand.Parameters.Add(par);
}
// Remove the last comma
sb.Remove(sb.ToString().LastIndexOf(','), 1);
// Add a where clause if a rowfilter was provided
if (rowFilter != string.Empty)
sb.AppendFormat("WHERE {0}", rowFilter);
// Set the command text
retCommand.CommandText = sb.ToString();
// Return the command
return retCommand;
}
映射正确的数据类型:
private static OleDbType GetOleDbType(Type inputType)
{
switch (inputType.FullName)
{
// Return the appropriate type
case "System.Boolean":
return OleDbType.Boolean;
case "System.Int32":
return OleDbType.Integer;
case "System.Single":
return OleDbType.Single;
case "System.Double":
return OleDbType.Double;
case "System.Decimal":
return OleDbType.Decimal;
case "System.String":
return OleDbType.Char;
case "System.Char":
return OleDbType.Char;
case "System.Byte[]":
return OleDbType.Binary;
default:
return OleDbType.Variant;
}
}
答案 0 :(得分:1)
今天早上弄清楚我的问题。我传递给GetUpdateCommand的'rowFilter'字符串导致了问题。我复制了这样的早期格式:
var rowFilter = string.Format("tag_unique_id = '{0}'", curTag);
我过去曾使用过这种类型的过滤器来查找文本值。因此,围绕字段值的单引号导致适配器将其解释为WHERE子句中的字符串。由于tag_unique_id字段是int32,因此它当然会在运行时抛出类型不匹配错误。解决办法就是将这些引号剥离出来:
var rowFilter = string.Format("tag_unique_id = {0}", curTag);
经验教训。