【问题标题】:Trying to call oracle function from dotnet getting error while returning value尝试从 dotnet 调用 oracle 函数在返回值时出错
【发布时间】:2019-12-02 09:48:18
【问题描述】:

我正在尝试从 asp.net mvc 端调用 oracle 函数并返回一个值,但出现错误“{”ORA-06502: PL/SQL: numeric or value error: string buffer too small\nORA-06512 : 在第 1 行"}。

在 oracle 方面,我编写了一个返回串联值的函数,然后在 dotnet 方面,我正在检索该值。

Oracle 函数

CREATE OR REPLACE FUNCTION func_multi_val(PROD_DATE in varchar2)
 RETURN varchar2  
 is 
  var_value varchar2(200);
  x varchar2     (200);
  cursor age_val is 
 SELECT AGE_CD,
 decode(AGE_CD,'04','CL LINE(R','05','CR ','A',NULL,STAGE_DESC) STAGE_DESC ,
 STAGE_SEQ      
 FROM DBPROD.PROD_AGE_MST
 WHERE STAGE_SEQ < 15
 AND STAGE_CD NOT IN ('ZA','05')
 ORDER BY 3;  
 BEGIN
    FOR i IN age_val LOOP
      SELECT To_Char(Round(NVL(SUM(NVL(WF_PROD_WT, 0)), 0), 0)) 
      INTO X
      FROM DBPROD.Prod_age_wp_gs_cur
     WHERE WF_DATE BETWEEN trunc(to_date(PROD_DATE,'dd-MM-YYYY')) AND  trunc(to_date(OD_DATE,'dd-MM-YYYY')+1)
       AND WF_STAGE_CD=i.AGE_CD;
    var_value := var_value || X||'~';
   END LOOP;
return var_value;
END;

Asp.net MVC

try
   {
    conn.Open();
    OracleCommand command = new OracleCommand();
    command.Connection = conn;
    command.CommandText = "func_multi_val";
    command.CommandType = CommandType.StoredProcedure;
    command.Parameters.Add("PROD_DATE", OracleDbType.Varchar2).Value = DateTime.Now.ToString("dd-MM-yyyy");
    command.Parameters.Add("var_value", OracleDbType.Varchar2).Direction = ParameterDirection.ReturnValue;
    command.ExecuteScalar();
    object o = command.ExecuteScalar();

     }  
     catch(Exception ex)
     {
     }

预期:连接值应从 dotnet 的 oracle 端检索返回。 实际:绑定“{”ORA-06502:PL/SQL:数字或值错误:字符串缓冲区太小\nORA-06512:在第 1 行“}”时在 dotnet 端出现错误。任何想法将不胜感激

【问题讨论】:

  • 从 .NET DateTime 传递 prod_date 作为日期开始,然后检查参数绑定顺序和 varchar2 大小。
  • var_value varchar2(200); --> var_value varchar2(32000);
  • @Tejash----ORA-00980 它不会再次出现同样的错误
  • x varchar2 (200); --> x varchar2 (4000);

标签: c# asp.net-mvc oracle ado.net


【解决方案1】:

另一种回答方式我只是从 oracle 查询中删除参数并使用 sysdate 函数而不是使用 PROD_DATE 变量

CREATE OR REPLACE FUNCTION func_multi_val
 RETURN varchar2  
 is 
  var_value varchar2(200);
  x varchar2     (200);
  cursor age_val is 
 SELECT AGE_CD,
 decode(AGE_CD,'04','CL LINE(R','05','CR ','A',NULL,STAGE_DESC) STAGE_DESC ,
 STAGE_SEQ      
 FROM DBPROD.PROD_AGE_MST
 WHERE STAGE_SEQ < 15
 AND STAGE_CD NOT IN ('ZA','05')
 ORDER BY 3;  
 BEGIN
    FOR i IN age_val LOOP
      SELECT To_Char(Round(NVL(SUM(NVL(WF_PROD_WT, 0)), 0), 0)) 
      INTO X
      FROM DBPROD.Prod_age_wp_gs_cur
     WHERE PSWF_DATE BETWEEN sysdate AND  sysdate+1
       AND WF_STAGE_CD=i.AGE_CD;
    var_value := var_value || X||'~';
   END LOOP;
return var_value;
END;

在 dotnet 端我做了以下修改

try
   {
    conn.Open();
    OracleCommand command = new OracleCommand();
    command.Connection = conn;
    command.CommandText = "func_multi_val";
    command.CommandType = CommandType.StoredProcedure;    
   command.Parameters.Add("var_value", OracleDbType.Varchar2,200).Direction = ParameterDirection.ReturnValue;
    command.ExecuteScalar();
    object o = command.Parameters["var_value"].Value;

     }  
     catch(Exception ex)
     {
     }

【讨论】:

    【解决方案2】:

    VAR_VALUE 包含连接结果。如果它(结果)超过 200 个字符,则不能放入 VARCHAR2(200) 变量中,因为 VAR_VALUE 是这样声明的。

    因此,放大它。

    【讨论】:

    • ORA-06502 是 Oracle 端出现的一个错误,所以...重新考虑并测试一下。
    • 我将 VAR_VALUE 数据类型更改为 clob,但现在出现错误 {"ORA-22275: invalid LOB locator specified\nORA-06512: at line 1"}
    • 为什么选择 CLOB?你真的期待那么大吗?试试VARCHAR2(32767)
    • 仍然得到同样的错误 {"ORA-06502: PL/SQL: 数字或值错误: 字符串缓冲区太小\nORA-06512: 在第 1 行"}
    • 好的。只是为了确保 VAR_VALUE 的大小是罪魁祸首:而不是 var_value := var_value || X||'~';,而是使用 var_value := substr(var_value || X||'~', 1, 1000);,这会将其缩短为 1000 个字符。忽略它可能/可能不会包含完整字符串长度的事实。
    猜你喜欢
    • 2020-04-10
    • 2020-08-17
    • 1970-01-01
    • 2015-10-05
    • 2023-01-14
    • 1970-01-01
    • 2021-09-16
    • 1970-01-01
    • 2010-10-15
    相关资源
    最近更新 更多