2017-02-27 43 views
1

当我的C#代码调用Oracle函数时,出现“空数据操作无效”错误。只有在找不到数据时才会发生这种情况。如果找到数据并且函数返回一个值,那么一切正常。我有点困惑,因为 - 至少我的理解 - 如果没有找到数据,函数应该返回100(参见函数异常)。C#调用Oracle函数 - 错误:“空数据无效操作”

Oracle函数:

create or replace FUNCTION F_SCO_DPD 
(
    p_tip IN NUMBER, 
    p_dav IN VARCHAR2 
) 
RETURN NUMBER 
IS 
    sco NUMBER; 
BEGIN 
    SELECT max(score) keep(dense_rank first order by vrednost) 
     INTO sco 
     FROM sco_sif_score 
     WHERE sif_kat = 11 
     AND tip_pod = p_tip 
     AND vrednost >= (SELECT a.dpd 
         FROM sco_dpd a          
         WHERE a.par_davcna = p_dav); 
    RETURN sco; 
EXCEPTION 
     WHEN NO_DATA_FOUND 
     THEN 
      RETURN 100; 
END F_SCO_DPD; 

C#代码:

using (OracleCommand cmd = new OracleCommand()) 
{ 
    cmd.Connection = conn; 
    cmd.CommandText = "F_SCO_DPD"; 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Parameters.Add(new OracleParameter("p_tip", Podjetje.TipSub)); 
    cmd.Parameters.Add(new OracleParameter("p_dav", Podjetje.Davcna)); 
    cmd.Parameters.Add(new OracleParameter("sco", OracleDbType.Decimal, ParameterDirection.ReturnValue)); 
    cmd.BindByName = true; 

    cmd.ExecuteScalar(); 

    Score.ScoDpd = (int)(OracleDecimal)cmd.Parameters["sco"].Value;          
} 

回答

2

您正在运行的聚合功能。 max(score) keep (dense_rank first order by vrednost)max(score)一样具有聚合功能。

这意味着您的查询是没有GROUP BY的聚合查询。所有这样的查询返回正好 1行。如果没有行匹配WHERE子句,则值为NULL

所以,这个例外从来没有被触发。相反,请检查返回值是否为NULL

产生的代码是:

create or replace FUNCTION F_SCO_DPD 
(
    p_tip IN NUMBER, 
    p_dav IN VARCHAR2 
) 
RETURN NUMBER 
IS 
    v_sco NUMBER; 
BEGIN 
    SELECT max(score) keep (dense_rank first order by vrednost) 
    INTO v_sco 
    FROM sco_sif_score 
    WHERE sif_kat = 11 AND 
      tip_pod = p_tip AND 
      vrednost >= (SELECT a.dpd 
         FROM sco_dpd a          
         WHERE a.par_davcna = p_dav 
        ); 

    RETURN COALESCE(v_sco, 100); 
END F_SCO_DPD; 
+0

谢谢,戈登。您的迅速答复和非常明确的解释。当然,它现在按预期工作。学到了新东西,所以谢谢你。赞成你的答案,但不能被看到,因为我的声望<15。 – Flin