【问题标题】:OracleCommand Update works with interpolated SQL, but not with ParameterizedOracleCommand Update 适用于插值 SQL,但不适用于 Parameterized
【发布时间】:2016-04-15 02:15:47
【问题描述】:

我正在对使用 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;
            }
        }
    }

【问题讨论】:

    标签: c# sql oracle parameterized-query oraclecommand


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢!这解决了我的问题。我没有意识到默认情况下它是按位置绑定的。我会很感激文档的链接。
    【解决方案2】:

    你必须设置

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

    【讨论】:

    • 谢谢!这解决了我的问题。我没有意识到默认情况下它是按位置绑定的。我将通读 Gary 发布的文档,并将我的参数更改为新格式。
    猜你喜欢
    • 1970-01-01
    • 2018-09-23
    • 1970-01-01
    • 2021-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多