OracleCommand更新适用于插值SQL,但不适用于参数化

问题描述:

我正在对传统应用程序进行一些维护,使用OracleConnection和OracleCommand来管理我们的数据。我遇到了一个问题,即当我使用参数时特定的更新不起作用,但如果我将相同的语句转换为插入的字符串,则工作正常。我没有收到任何异常,更新不会发生,并且为更新的行返回0。我正在用参数进行其他更新,所以我很好奇,如果有人看到我可能错过的任何内容。我尝试了/不使用事务,也没有明确地创建OracleParameter对象。OracleCommand更新适用于插值SQL,但不适用于参数化

该方法如下。我已将参数化版本和参数设置注释掉以供参考。

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; 
      } 
     } 
    } 

我怀疑你是按位置而不是名称绑定参数。

按位置,你会先将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

+0

谢谢!这解决了我的问题。我没有意识到这是默认情况下的绑定。我会很感激链接到文档。 –

要么你必须设置

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),则其他数据类型(例如日期)可能会失败。

+0

谢谢!这解决了我的问题。我没有意识到这是默认情况下的绑定。我将通读Gary发布的文档,并将我的参数更改为新格式。 –