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
相关产品推荐
相关产品推荐

