C#调用Oracle函数 - 错误:"对空数据的操作无效"

时间:2017-02-27 11:56:28

标签: c# oracle

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

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;                                    
}

1 个答案:

答案 0 :(得分: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;