Search notes:

NULL related Oracle functions

Some Oracle functions that are related to null.

NVL

nvl is lazily evaluated:
--
--     Demonstrating that NVL is not evaluating lazily.
--

create table tq84_a (
  a number          primary key,
  b varchar2(10)
);

create table tq84_b (
  c number          primary key,
  d number
);

create function tq84_f(a in number) return varchar2
is
begin
 
    dbms_output.put_line('function was called: ' || a);

    return '* ' || a || ' *';

end tq84_f;
/


insert into tq84_a values (1, 'one'  );
insert into tq84_a values (2,  null  );
insert into tq84_a values (3,  null  );
insert into tq84_a values (4, 'four' );

insert into tq84_b values (2,  20);
insert into tq84_b values (4,  40);

select
  substr(tq84_f(a), 1, 10) a,
  b,
  substr(nvl (
    b,
   (select tq84_f(d) from tq84_b where c = a)
  )
  ,1,10) c
from
  tq84_a
order by a;
  

drop table tq84_a purge;
drop table tq84_b purge;

drop function tq84_f;
Github repository Oracle-Patterns, path: /SQL/functions/null_related/nvl_not_lazy_evaluated.sql
The SQL Server equivalent for nvl is isNull.

NVL2

nvl2(tested_value, 'value if not null', 'value if null')
create table tq84_nvl2 (
  a number
);

insert into tq84_nvl2 values (null);
insert into tq84_nvl2 values (   0);
insert into tq84_nvl2 values (  42);

select
  a,
  nvl2(a, 'not null', 'null')
from
  tq84_nvl2;

drop table tq84_nvl2 purge;
Github repository Oracle-Patterns, path: /SQL/functions/null_related/nvl2.sql

LNNVL

lnnvl is equivalent to the SQL standard's is not true predicate (compare feature F571).
Assuming that A and B are expressions that evaluate to a non-null value, the following is the result table of lnnvl:
lnnvl( A = A) false
lnnvl( A = B) true
lnnvl( A = null) true
lnnvl(null = null) true
lnnvl can only be used in where clauses.
create table tq84_lnnvl (
       col1  number,
       col2  number
);

insert into tq84_lnnvl values (null, null);
insert into tq84_lnnvl values (null,    1);
insert into tq84_lnnvl values (   1,    1);
insert into tq84_lnnvl values (   1,    2);

select * from tq84_lnnvl where lnnvl(col1=col2);
--
--       COL1       COL2
-- ---------- ----------
-- 
--                     1
--          1          2

select * from tq84_lnnvl where not lnnvl(col1=col2);
--       COL1       COL2
-- ---------- ----------
--          1          1

drop table tq84_lnnvl purge;
Github repository Oracle-Patterns, path: /SQL/functions/null_related/lnnvl.sql

NULLIF

NULLIF(X, Y) is equivalent to CASE WHEN X = Y THEN NULL ELSE X END, i. e. it evaluates to X unless X is equal to Y in which case it evaluates to null.
with expr as (
  select 'foo' val from dual union all
  select 'baz' val from dual union all
  select 'bar' val from dual union all
  select  null val from dual
)
select
  first.val, second.val, 
  nullif(first.val, second.val) "Null if equal, first otherwise",
  case when first.val = second.val then null else first.val end "same same"
from
  expr first, expr second
where
  first.val is not null;
Github repository Oracle-Patterns, path: /SQL/functions/null_related/nullif.sql
nullif is especially useful to prevent ORA-01476: divisor is equal to zero errors.

See also

sys_op_map_nonnull allows to compare two values, even if they're null.
Oracle SQL functions

Index