OracleCommand Update работает с интерполированным SQL, но не с параметризованным.

Я занимаюсь обслуживанием устаревшего приложения, которое использует OracleConnection и OracleCommand для управления нашими данными. У меня возникла проблема, когда конкретное обновление не работает, когда я использую параметры, но если я преобразую тот же оператор в интерполированную строку, он работает нормально. Я не получаю никаких исключений, обновление просто не происходит и возвращает 0 для обновленных строк. Я делаю другие обновления с параметрами, поэтому мне любопытно, увидит ли кто-нибудь что-нибудь, что я мог пропустить с этим. Я пробовал с/без транзакции, а также явно создавал объекты OracleParameter безрезультатно.

Способ ниже. Я оставил параметризованную версию, а настройку параметра закомментировал для справки.

    public int UpdateBusinessEntitlement(int appId, int businessId, int entitlementTypeId, string sso)
    {

        // Non-Working Parameterized Version
        //var sql = "UPDATE APD.APD_BUS_TO_APP_MAP " +
        //                   "SET ENTITLEMENT_TYPE_SEQ_ID = :entitlementTypeId, " +
        //                   "LAST_UPDATE_DATE = SYSDATE, " +
        //                   "LAST_UPDATED_BY = :lastUpdatedBy " +
        //                   "WHERE APP_SEQ_ID = :appId AND BUSINESS_SEQ_ID = :businessId";

        var sql = "UPDATE APD.APD_BUS_TO_APP_MAP " +
               $"SET ENTITLEMENT_TYPE_SEQ_ID = {entitlementTypeId}, " +
               "LAST_UPDATE_DATE = SYSDATE, " +
               $"LAST_UPDATED_BY = {sso} " +
               $"WHERE APP_SEQ_ID = {appId} AND BUSINESS_SEQ_ID = {businessId}";


        using (var cn = _connectionBuilder.GetUpdaterConnection())
        {
            using (var cmd = _connectionBuilder.GetCommand(sql, cn))
            {
                cn.Open();
                var transaction = cn.BeginTransaction(IsolationLevel.ReadCommitted);
                cmd.Transaction = transaction;

                //cmd.Parameters.Add("appId", appId);
                //cmd.Parameters.Add("businessId", businessId);
                //cmd.Parameters.Add("entitlementTypeId", entitlementTypeId);
                //cmd.Parameters.Add("lastUpdatedBy", sso);


                var rows = cmd.ExecuteNonQuery();
                transaction.Commit();

                return rows;
            }
        }
    }

person Mike Whitis    schedule 15.04.2016    source источник


Ответы (2)


Я подозреваю, что вы привязываете параметры по положению, а не по имени.

По положению вы бы поместили appId первым в entitlement_type_seq_id. Затем BusinessId в last_Updated_By, entitlementTypeId в app_seq_id и lastUpdatedBy в business_seq_id.

https://docs.oracle.com/cd/B19306_01/win.102/b14307/OracleCommandClass.htm#i997666

person Gary Myers    schedule 15.04.2016
comment
Спасибо! Это решило мою проблему. Я не понимал, что по умолчанию он привязывается по положению. Буду признателен за ссылку на документы. - person Mike Whitis; 15.04.2016

Либо вы должны установить

cmd.BindByName = true;

потому что значение по умолчанию для свойства BindByName равно false, что означает, что параметры привязаны к положению.

Или вы должны использовать тот же порядок параметров, что и в вашем заявлении, т.е.

cmd.Parameters.Add("entitlementTypeId", entitlementTypeId);
cmd.Parameters.Add("lastUpdatedBy", sso);
cmd.Parameters.Add("appId", appId);
cmd.Parameters.Add("businessId", businessId);

Кстати, обычно OracleParameter добавляются так:

cmd.Parameters.Add("entitlementTypeId", OracleDbType.Int32, ParameterDirection.Input).Value = entitlementTypeId;
cmd.Parameters.Add("lastUpdatedBy", OracleDbType.Varchar2, ParameterDirection.Input).Value = entitlementTypeId;
cmd.Parameters.Add("appId", OracleDbType.Int32, ParameterDirection.Input).Value = appId;
cmd.Parameters.Add("businessId", OracleDbType.Int32, ParameterDirection.Input).Value = businessId;

Я предполагаю, что для простых типов данных, таких как числа строк, синтаксис не имеет значения, однако другие типы данных (например, Дата) могут не работать, если вы просто используете cmd.Parameters.Add(string name, object val).

person Wernfried Domscheit    schedule 15.04.2016
comment
Спасибо! Это решило мою проблему. Я не понимал, что по умолчанию он привязывается по положению. Я прочитаю документы, опубликованные Гэри, и изменю свои параметры на новый формат. - person Mike Whitis; 15.04.2016