Oracle: Get a query to always return exactly one row, even when there's no data to be found

前端 未结 6 1666
余生分开走
余生分开走 2021-01-18 01:17

I have a query like this:

   select data_name
   into v_name
   from data_table
   where data_table.type = v_t_id

Normally, this query shou

相关标签:
6条回答
  • 2021-01-18 01:47

    There's ways to make this simpler and cleaner, but this basically spells out the technique:

    SELECT data_name
    FROM data_table
    WHERE data_table.type = v_t_id
    
    UNION ALL
    
    SELECT NULL AS data_name
    FROM dual
    WHERE NOT EXISTS (
        SELECT data_name
        FROM data_table
        WHERE data_table.type = v_t_id
    )
    

    When the first part of the union is empty the second will contain a row, when the first part is not empty, the second will contain no rows.

    If the query is takes to much time, use this one:

    SELECT * FROM (  
        SELECT data_name
        FROM data_table
        WHERE data_table.type = v_t_id
    
        UNION ALL
    
        SELECT NULL AS data_name
        FROM dual
      ) WHERE data_name is not null or ROWNUM = 1
    
    0 讨论(0)
  • 2021-01-18 01:48

    If you always expect zero or one row then you can use a group function i.e.:

    select dump(max(dummy)) from dual
    where dummy = 'Not Found'
    

    You will always get at least one row and a value of NULL in the case where the record is not found.

    0 讨论(0)
  • 2021-01-18 01:54

    I would prefer to handle the exception. However, this would work as you specify:

    select min(data_name) data_name
    into v_name
    from data_table
    where data_table.type = v_t_id
    

    Note that this also "works" if the query returns more than 1 row - i.e. TOO_MANY_ROWS is not raised.

    0 讨论(0)
  • 2021-01-18 01:54

    Here is my simple solution using LEFT OUTER JOIN:

    CREATE TABLE data_table(data_name VARCHAR2(20), data_type NUMBER(2));
    
    INSERT INTO data_table(data_name, data_type) VALUES('fifty-one', 51);
    
    SELECT coalesce(data_name, 'unknown')
      FROM dual
      LEFT OUTER JOIN (SELECT data_name FROM data_table WHERE data_type = 53) o
        ON 1 = 1;
    
    SELECT coalesce(data_name, 'unknown')
      FROM dual
      LEFT OUTER JOIN (SELECT data_name FROM data_table WHERE data_type = 51) o
        ON 1 = 1;
    
    0 讨论(0)
  • 2021-01-18 01:54

    https://stackoverflow.com/a/4683045/471149 answer is nice, but there is shorter solution

    select * from my_table ce, (select 150 as id from dual) d
    where d.id = ce.entry_id (+)
    
    0 讨论(0)
  • 2021-01-18 02:03
     select coalesce(data_table.data_name, d.data_name) data_name
       into v_name
       from 
       (SELECT 'UNKNOWN ' as data_name FROM DUAL)  d
       LEFT JOIN data_table
       ON data_table.type = v_t_id
              or a.data_table.data_name is null
    
    0 讨论(0)
提交回复
热议问题