当select语句返回没有找到数据时,如何返回Null

时间:2017-03-09 07:48:07

标签: oracle oracle12c

我有这三个select语句,并且当没有找到数据时,我试图将null返回到变量vCLASS1_IDvCLASS2_IDvCLASS3_ID

  SELECT MAX (CLASS1_ID), MAX(CLASS1_DESC)
    INTO vCLASS1_ID, vCLASS1_DESC
    FROM PRODUCT_CLASSIFICATION
   WHERE CLASS1_DESC = P_CLASS1_DESC
GROUP BY CLASS1_ID, CLASS1_DESC;

   SELECT MAX (CLASS2_ID),MAX(CLASS2_DESC)
     INTO vCLASS2_ID,vCLASS2_DESC
     FROM PRODUCT_CLASSIFICATION
    WHERE CLASS2_DESC = P_CLASS2_DESC
GROUP BY CLASS2_ID, CLASS2_DESC;

   SELECT MAX (CLASS3_ID),MAX(CLASS3_DESC)
     INTO vCLASS3_ID,vCLASS3_DESC
     FROM PRODUCT_CLASSIFICATION
    WHERE CLASS3_DESC = P_CLASS3_DESC
GROUP BY CLASS3_ID, CLASS3_DESC;

我试图通过以下方式解决这个问题,但我失败了

    使用return null变量的
  • EXCEPTION when no_data_found then无法解决我的问题,因为该函数将停止运行

  • 我尝试使用NULLIF函数如下所示,但是当有wher e子句时,它不会返回null,当我删除where子句时,我将无法获得单记录:

    SELECT NULLIF (CLASS1_DESC, 'EXAMPLE') AS CLASS1_DESC FROM PRODUCT_CLASSIFICATION ---WHERE CLASS1_DESC = 'EXAMPLE' GROUP BY CLASS1_DESC

还有其他简单方法吗?

声明3 courser是更好的解决方案吗?

2 个答案:

答案 0 :(得分:3)

  

"当no_data_found使用EXCEPTION然后变量将无法解决我的问题,因为该函数将停止运行"

使用匿名块来定义本地异常部分。此方法允许您单独处理每个事件,而不会导致较大的程序单元异常终止。

begin
      SELECT CLASS1_ID 
      INTO vCLASS1_ID
        FROM PRODUCT_CLASSIFICATION
       WHERE CLASS1_DESC = 'EXAMPLE';
exception
    when no_data_found then
        vCLASS1_ID := null;
end;        

begin
      SELECT CLASS2_ID 
      INTO vCLASS2_ID
        FROM PRODUCT_CLASSIFICATION
       WHERE CLASS2_DESC = 'EXAMPLE';
exception
    when no_data_found then
        vCLASS2_ID := null;
end;        

begin
      SELECT CLASS3_ID 
      INTO vCLASS3_ID
        FROM PRODUCT_CLASSIFICATION
       WHERE CLASS3_DESC = 'EXAMPLE';
exception
    when no_data_found then
        vCLASS3_ID := null;
end;        

上述解决方案是处理异常的一般方法。但是,@ MaheswaranRavisankar建议的解决这个特殊问题的解决方案(当没有找到数据时将变量设置为null)需要更少的输入:

      SELECT max(CLASS3_ID) 
      INTO vCLASS3_ID
        FROM PRODUCT_CLASSIFICATION
       WHERE CLASS3_DESC = 'EXAMPLE';

这种方法的潜在优势在于,如果我们采用OP的原始配方,它将不会返回任何行:

 SELECT max(CLASS3_ID) 
      INTO vCLASS3_ID
        FROM PRODUCT_CLASSIFICATION
       WHERE CLASS3_DESC = 'EXAMPLE'
 GROUP BY CLASS3_ID;

目前尚不清楚OP为何在原始查询中使用GROUP BY。如果该表有可能存在重复的CLASSn_ID,那么正确的方法是:

    如果存在重复项,则
  • 投掷并处理TOO_MANY_ROWS异常
  • 应用建立当前有效类ID的业务规则

然而,如果这些都不能满足剩下的开放方法

begin
      SELECT CLASS3_ID 
      INTO vCLASS3_ID
        FROM PRODUCT_CLASSIFICATION
       WHERE CLASS3_DESC = 'EXAMPLE'
      GROUP BY CLASS3_ID;
exception
    when no_data_found then
        vCLASS3_ID := null;
end;    

答案 1 :(得分:1)

我认为可以通过使用外连接

来完成
"rails g controller abc"