If the only valid scenario is to fill the fields in order, with no gaps, which I think is what you're saying, then you could work out the 'highest' field that is populated and the number of fields that are populated, and compare them. If there us a gap then those two numbers will be different. e.g.:
select field1, field2, field3, field4, field5 from (
select field1, field2, field3, field4, field5,
case when field1 is not null then 1 else 0 end
+ case when field2 is not null then 1 else 0 end
+ case when field3 is not null then 1 else 0 end
+ case when field4 is not null then 1 else 0 end
+ case when field5 is not null then 1 else 0 end as cnt,
greatest(case when field1 is not null then 1 else 0 end,
case when field2 is not null then 2 else 0 end,
case when field3 is not null then 3 else 0 end,
case when field4 is not null then 4 else 0 end,
case when field5 is not null then 5 else 0 end) as grt
from my_table
)
where cnt != grt;
SQL Fiddle demo.
As Michael-O points out, you could use nvl2
instead of case
(shown in another SQL Fiddle), which is non-standard but arguably clearer:
select field1, field2, field3, field4, field5 from (
select field1, field2, field3, field4, field5,
nvl2(field1, 1, 0) + nvl2(field2, 1, 0) + nvl2(field3, 1, 0)
+ nvl2(field4, 1, 0) + nvl2(field5, 1, 0) as cnt,
greatest(nvl2(field1, 1, 0), nvl2(field2, 2, 0), nvl2(field3, 3, 0),
nvl2(field4, 4, 0), nvl2(field5, 5, 0)) as grt
from t42
)
where cnt != grt;
If you wanted to enforce this you could add a check constraint to do the same comparison:
alter table my_table add constraint my_check check (
case when field1 is not null then 1 else 0 end
+ case when field2 is not null then 1 else 0 end
+ case when field3 is not null then 1 else 0 end
+ case when field4 is not null then 1 else 0 end
+ case when field5 is not null then 1 else 0 end
= greatest(case when field1 is not null then 1 else 0 end,
case when field2 is not null then 2 else 0 end,
case when field3 is not null then 3 else 0 end,
case when field4 is not null then 4 else 0 end,
case when field5 is not null then 5 else 0 end));
Since you're using 11gR2 you could do this with virtual columns as well:
alter table my_table add cnt generated always as
(case when field1 is not null then 1 else 0 end
+ case when field2 is not null then 1 else 0 end
+ case when field3 is not null then 1 else 0 end
+ case when field4 is not null then 1 else 0 end
+ case when field5 is not null then 1 else 0 end);
alter table my_table add grt generated always as
(greatest(case when field1 is not null then 1 else 0 end,
case when field2 is not null then 2 else 0 end,
case when field3 is not null then 3 else 0 end,
case when field4 is not null then 4 else 0 end,
case when field5 is not null then 5 else 0 end));
alter table my_table add constraint my_check check (cnt = grt);
... but apart from the check itself maybe being clearer I don't think it adds much.