使用 IDataParameter 更新在 Oracle 中不起作用

Update using IDataParameter not working in Oracle

我有一个 C# 摘要 class 用于实现数据库事务,它具有 SQL (System.Data.SqlClient) 和 Oracle (Oracle.ManagedDataAccess.Client) 实现。

public int ExecuteDML<T>(string sql, List<T> objects)
{
    int cnt = 0;
    using (IDbConnection conn = GetConnection())
    {
        using (IDbTransaction txn = conn.BeginTransaction())
        {
            using (IDbCommand cmd = conn.CreateCommand())
            {
                cmd.CommandType = CommandType.Text;
                cmd.CommandText = PrepSQL(sql);                        
                cmd.Transaction = txn;
                try
                {
                    foreach (T obj in objects)
                    {
                        cmd.Parameters.Clear();
                        foreach (var kvp in GetDbParameters<T>(obj))
                        {
                            IDataParameter param = new DbParameter
                            {
                                ParameterName = kvp.Key,
                                Value = kvp.Value ?? DBNull.Value
                            };
                            cmd.Parameters.Add(param);
                        }

                        cnt += cmd.ExecuteNonQuery();                                
                    }
                    txn.Commit();
                }
                catch (Exception)
                {
                    txn.Rollback();
                    throw;
                }
            }
        }
    }
    return cnt;
}

我能够在两种实现中执行 INSERT、UPDATE 和 DELETE 语句。但是当我 运行 在 Oracle 实现中进行更新时,记录不会在数据库中更新; ExecuteNonQuery returns 0。但是,SQL 实现中的相同 data/command 工作正常。

为什么参数化查询不适用于 UPDATE,而 INSERT 和 DELETE 却可以?

查询

UPDATE CONFIG_PARAMS SET PARAM_VALUE = :ParamValue, LOAD_DATE = :LoadDate, UPDATED_BY = :UpdatedBy WHERE ACTION_NAME = :ActionName AND PARAM_NAME = :ParamName

this post 中找到了解决方案。 BindByName 需要为 Oracle 明确设置设置,因为参数顺序不正确。

我在创建 IDbCommand

后添加了这段代码
if (cmd is Oracle.ManagedDataAccess.Client.OracleCommand)
{
    ((Oracle.ManagedDataAccess.Client.OracleCommand)cmd).BindByName = true;
}