OleDb Update命令在清除DataTable中的Byte[]值时抛出数据类型不匹配

本文关键字:不匹配 数据类型 Byte 命令 Update 清除 中的 DataTable OleDb | 更新日期: 2023-09-27 18:18:41

我有一个通过OleDb连接更新MS Access数据库的现有方法。我过去曾使用此方法更新数据,但是现在我在访问表中添加了一个图像字段(OLE Object存储为长二进制数据),因此出现了类型不匹配错误。为了从访问数据库检索数据,我从OleDbdataAdapter填充了一个DataTable,这是标准的东西。我可以从数据库中提取图像,并使其显示完美,因此我知道它被正确存储。

为了将数据表中的值更新到文件数据库中,我从数据表字段动态构建更新命令,并为每个字段包含参数。要将字段类型从系统类型映射到OleDbType,我使用返回所需类型的简单switch方法。

一切都按照它应该的方式工作,除了当我想从DataTable中的特定行清除图像字段,然后更新数据库时。DataTable显示正确的空值,但是当调用update命令时,它会抛出此错误。我试过将字段的值设置为字符串。empty, null和DbNull。值,都没用。

我必须以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;
        }
    }

OleDb Update命令在清除DataTable中的Byte[]值时抛出数据类型不匹配

今天早上我明白我的问题了。我传递给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);

教训。