Обновление с использованием IDataParameter не работает в Oracle - PullRequest
0 голосов
/ 07 января 2020

У меня есть C# абстрактный класс для реализации транзакций базы данных, который имеет реализацию 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 в обеих реализациях. Но когда я запускаю UPDATE в реализации Oracle, запись не обновляется в базе данных; ExecuteNonQuery возвращает 0. Однако те же данные / команда в реализации SQL работают нормально.

Почему параметризованный запрос не будет работать для UPDATE, тогда как INSERT и DELETE - это нормально?

Запрос

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

1 Ответ

0 голосов
/ 07 января 2020

Нашел решение в этом посте . Параметр BindByName необходимо установить явно для Oracle, поскольку параметры были не в порядке.

Я добавил этот код после создания IDbCommand

if (cmd is Oracle.ManagedDataAccess.Client.OracleCommand)
{
    ((Oracle.ManagedDataAccess.Client.OracleCommand)cmd).BindByName = true;
}
...