带有参数的 Oledb 更新命令在 access-db 上不起作用

Posted

技术标签:

【中文标题】带有参数的 Oledb 更新命令在 access-db 上不起作用【英文标题】:Oledb update-command with parameters not working on access-db 【发布时间】:2018-10-04 13:42:41 【问题描述】:

我的 c# 应用程序有问题。我尝试通过 oledb-connection 更新访问数据库。

这是表的架构:

这是我正在使用的功能:

public override int Update(string tableName, Action<ISqlParameterizer> actionSqlParameterizerUpdate, Action<ISqlParameterizer> actionSqlParameterizerWhere)

    var commandText = $"update tableName set @update where @where";

    var whereBuilder = new StringBuilder();
    var updateBuilder = new StringBuilder();
    var whereParameterizer = SqlParameterizer.CreateFrom(this);
    var updateParameterizer = SqlParameterizer.CreateFrom(this);

    actionSqlParameterizerWhere?.Invoke(whereParameterizer);
    actionSqlParameterizerUpdate?.Invoke(updateParameterizer);

    List<IDbDataParameter> parameterList = new List<IDbDataParameter>();

    foreach (var whereParameter in whereParameterizer.GetParameters())
    
        whereBuilder.Append($" and whereParameter.ParameterName = @whereParameter.ParameterName");
        parameterList.Add(whereParameter);
    
    foreach (var updateParameter in updateParameterizer.GetParameters())
    
        updateBuilder.Append($", updateParameter.ParameterName = @updateParameter.ParameterName");
        parameterList.Add(updateParameter);
    

    commandText = commandText.Replace("@where", whereBuilder.ToString().Substring(4));
    commandText = commandText.Replace("@update", updateBuilder.ToString().Substring(1));

    return base.ExecuteNonQuery(commandText, parameterList.ToArray());

commandtext-property 如下所示:

更新 MY_TABLE 设置 MY_COLUMN = @MY_VALUE 其中 SOME_COLUMN = @SOME_VALUE

SOME_COLUMN的数据类型是numeric,MY_COLUMN的数据类型是Memo

两个参数都是 oledbtype 整数。我尝试将MY_COLUMN的参数添加为字符串,所以参数是VarWChar,但这没有区别。

运行该命令后没有任何反应,没有更新任何行。当我在 Access 本身中输入命令文本并执行语句时。 Access 会询问我的参数值。我输入我的值并更新行。

为什么这不适用于我的 oledb 连接?


问题似乎出在我正在使用的 SqlContext 类上。

使用普通的 OleDbConnection:

using (var connection = new OleDbConnection(CONNECTION_STRING_ACCESS))

    connection.Open();
    using (var command = connection.CreateCommand())
    
        command.CommandText = $"UPDATE MY_TABLE SET MY_COLUMN = @MY_VALUE WHERE SOME_COLUMN = @SOME_VALUE";
        command.Parameters.Add(new OleDbParameter("MY_COLUMN", "MY_VALUE"));
        command.Parameters.Add(new OleDbParameter("SOME_COLUMN", 1));
        command.ExecuteNonQuery();
    

工作得很好......

使用我的课程:

using (var accessContext = SqlContext.Create(CONNECTION_STRING_ACCESS, SqlProvider.AccessSql))

    accessContext.Update("MY_TABLE", update => 
        update.Add("MY_COLUMN", "MY_VALUE");
    , where => 
        where.Add("SOME_COLUMN", 1);
    );

没用……

我比较了两个版本的 commandtext-objekt 和参数对象,它们是相同的(“MY_COLUMN”的值除外,否则我无法识别该行是否已更新)。 (我无法添加屏幕截图,因为堆栈溢出说“不支持格式”,有趣的是,当我尝试添加第二个屏幕截图时,我能够毫无问题地添加我的第一个屏幕截图(.bmp)( .bmp) 显示错误)。

任何建议是什么导致了问题?

【问题讨论】:

没有错误被抛出? 不...行只是没有得到更新。 【参考方案1】:

您的参数顺序不正确。这两个循环应该按照它们在代码中出现的顺序进行切换。

这很重要,OleDbCommand 不使用命名参数。它们是基于它们在 sql 语句中出现的位置的序数。

Documentation - OleDbCommand.Parameters

当 CommandType 设置为 Text 时,OLE DB .NET 提供程序不支持将参数传递给 SQL 语句或由 OleDbCommand 调用的存储过程的命名参数。在这种情况下,必须使用问号 (?) 占位符。

...

因此,OleDbParameter 对象添加到 OleDbParameterCollection 中的顺序必须直接对应于命令文本中参数的问号占位符的位置


您的代码:

// should occur 2nd
foreach (var whereParameter in whereParameterizer.GetParameters())

    whereBuilder.Append($" and whereParameter.ParameterName = @whereParameter.ParameterName");
    parameterList.Add(whereParameter);


// should occur 1st
foreach (var updateParameter in updateParameterizer.GetParameters())

    updateBuilder.Append($", updateParameter.ParameterName = @updateParameter.ParameterName");
    parameterList.Add(updateParameter);

【讨论】:

以上是关于带有参数的 Oledb 更新命令在 access-db 上不起作用的主要内容,如果未能解决你的问题,请参考以下文章

更新查询在带有 MS Access 的 VB.NET 中不起作用

将企业库用于 OLEDB Access 数据库

JET OLEDB 参数如何将字符串与 Access DB 中的文本字段进行比较

使用 c# 和 oledb 查询更新 Ms-Access 2010 中的列值

C# MD5 和/或其他加密 oledb (access 2007)

C# OleDB SQL 插入命令