You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle存储过程对应C#后端代码返回-1,求修正建议

问题分析与修正建议

核心问题

代码返回-1的关键原因是错误把ExecuteSqlRaw的返回值当作存储过程的输出参数值——ExecuteSqlRaw返回的是SQL语句执行后受影响的行数,而存储过程生成的C_E_ID是通过输出参数传递的,和这个返回值完全无关。此外代码还存在变量冲突、未声明变量等问题,具体修正如下:

具体修正点

  • 修正返回值获取逻辑:放弃ExecuteSqlRaw的返回值,从输出参数C_E_ID中提取实际生成的ID值。
  • 解决PL/SQL变量名冲突:DECLARE块里的变量和输出参数同名,会导致值无法正确传递,需要重命名内部变量。
  • 声明未定义变量:补充ce_id变量的声明。
  • 完善异常处理:空catch块会掩盖错误,建议添加日志或抛出异常,方便排查问题。
  • 优化参数配置:为Oracle输出参数指定精度,避免类型转换异常。

修正后的代码

public int InsertCustomerEvaluation(string CUST_ID)
{
    // 声明输出参数,指定精度匹配Oracle NUMBER类型
    OracleParameter C_E_ID = new OracleParameter("C_E_ID", OracleDbType.Decimal, 10)
    {
        Direction = ParameterDirection.Output
    };

    // 声明要返回的变量
    int ce_id = 0;

    try
    {
        // 修正PL/SQL块:重命名内部变量,避免和输出参数冲突
        _context.Database.ExecuteSqlRaw(
            "DECLARE internal_C_E_ID NUMBER; BEGIN CEF_APP.InsertCustomerEvaluation(:CUST_ID, internal_C_E_ID); :C_E_ID := internal_C_E_ID; END;",
            new OracleParameter("CUST_ID", CUST_ID), 
            C_E_ID);

        // 从输出参数中提取值并转换为int
        if (C_E_ID.Value != DBNull.Value)
        {
            ce_id = Convert.ToInt32(C_E_ID.Value);
        }
    }
    catch (Exception e)
    {
        // 替换为你的日志逻辑,比如logger.LogError(e, "插入客户评价失败");
        throw; // 或者根据业务需求处理异常,不要吞掉异常
    }

    return ce_id;
}

额外说明

  • 确保你的EF Core版本支持Oracle参数的正确处理,若使用Oracle官方驱动,需注意参数名的大小写匹配(Oracle默认不区分,但建议和存储过程参数名保持一致)。
  • 存储过程中SCORE字段插入空字符串'',如果该字段是数值类型会报错,若SQL Developer运行正常,说明SCORE是字符类型,若后续改为数值类型,需修改存储过程的插入值。

内容的提问来源于stack exchange,提问作者YRandeeka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 17:14:52