14 december 2023

Oracle Database has known the Boolean datatype in PL/SQL since its introduction in Oracle Database version 7. However, until Oracle Database 23c, we had to use convoluted column definitions, such as char( 1 ), varchar2( 1 ), or number( 1 ), and add check constraints to tables to ensure that only valid data was entered.  With the introduction of the new Boolean datatype in Oracle Database 23c, most of these workarounds are no longer necessary.

Oracle Database 23c introduces a Boolean datatype which can be stored in the database, just likenumbers, strings, and dates. For example:

create table if not exists booleandemo
( id    number         generated by default on null as identit
, text  varchar2( 32 )
, value boolean
)
/

The "IF NOT EXISTS" construct is a new feature of Oracle Database 23c, as seen in the "If [Not] Exists" documentation.

 

Now we can easily add Boolean values to the table, including NULL, as Oracle has implemented the NULL ‘value’ throughout the database.

insert into booleandemo
  ( text,    value )

values
  ( q'[true]',      true    ) -- equals to true
, ( q'[false]',     false   ) -- equals to false
, ( q'[null]',      null    ) -- equals to null
/

The Multi-Row-Insert construct is another new feature of Oracle Database 23c, as seen in the Table Values Constructor documentation.

 

In addition to using true and false, you can also use numbers to represent Boolean value. In this case, 0 equals false, and any other value equals true, except for NULL of course, which will remain, well, NULL.

insert into booleandemo
  ( text, value )

values
  ( q'[-1]',      -1       ) -- equals to true
, ( q'[0]',        0       ) -- equals to false
, ( q'[1]',        1       ) -- equals to true
, ( q'[2]',        2       ) -- equals to true
/

And there are also a couple of string-pairs that automagically get converted to Boolean values, such as ( ‘y’, ’n’ ),( ‘yes’, ‘no’ ), ( ‘true’, ‘false’ ), ( ‘on’, ‘off’ ) and ( ‘yes’, ‘no’ ). The strings are case insensitive, so, for example, ‘TRUE’ and ‘FALSE’ are also valid.

insert into booleandemo
  ( text,        value   )

values
  ( q'['t']',     't'     ) -- equals to true
, ( q'['f']',     'f'     ) -- equals to false
, ( q'['true']',  'true'  ) -- equals to true
, ( q'['false']', 'false' ) -- equals to false
, ( q'['on']',    'on'    ) -- equals to true
, ( q'['off']',   'off'   ) -- equals to false
, ( q'['yes']',   'yes'   ) -- equals to true
, ( q'['no']',    'no'    ) -- equals to false
, ( q'['y']',     'y'     ) -- equals to true
, ( q'['n']',     'n'     ) -- equals to false
/

 

Any other value will result in an error (ORA-61800: invalid boolean literal).

If you query the data from the table with an Oracle Client older than 23c, you will see numbers, instead of the Boolean values, with, 0 representing false and 1 representing true. As you can see by the alignment of the column (right aligned), they are returned as a number.

select *
from   booleandemo
/

ID TEXT                                         VALUE
---------- -------------------------------- ----------
         1 true                                      1
         2 false                                     0
         3 null
...

If you query the data from the table with an Oracle Client 23c or higher, you will see the Boolean values:

select *
from   booleandemo
/

        ID TEXT                             VALUE
---------- -------------------------------- -----------
         1 true                             TRUE
         2 false                            FALSE
         3 null
...

PL/SQL
You can now also use the Boolean value in PL/SQL, for instance when logging information or writing the value to output. But be aware, this requires the parameter PLSQL_IMPLICIT_CONVERSION_BOOL to be set, which is not enabled by default.

This script will fail if the parameter is not enabled:

declare
  v_b boolean := true;
begin
  dbms_output.put_line( 'my bool is: ' || v_b );
end;
/ORA-06550: line 4, column 24:
PLS-00306: wrong number or types of arguments in call to '||'
ORA-06550: line 4, column 3:
PL/SQL: Statement ignored

If your DBA enables this parameter for the entire database, or if you enable it for your current session, the same script will complete successfully:

alter session set PLSQL_IMPLICIT_CONVERSION_BOOL=true
/

Session altered

declare
  v_b boolean := true;
begin
  dbms_output.put_line( 'my bool is: ' || v_b );
end;
/
my bool is: TRUE

Aggregates
Suprisingly, it is even possible to perform aggregation functions on a Boolean column. You can use a min( <column> ) and a max( <column> ) function on the column, where the min( <column> ) function will return false if there are one or more false values in the column and the max( <column> ) function will return true if there are one or more true values in the column.

You can also run sum( <column> ) on the column, which will give you the number of true values in the column. If you would like to see the number of false values, you can do so by querying sum( not <column> ). You can query the avg( <column> ) to get a feeling of how many true values there are compared to the number of false values. I have not tested all available aggregates, but it seems that Oracle Database internally represents false values as 0 and true values as 1, no matter what you used to populate the column.

This might not be the most prominent new feature of Oracle Database 23c, but it is certainly one that a lot of people have been eagerly waiting for.

 

The source code used in this article can be found at:
https://github.com/Qualogy-Solutions/OracleDatabase23c/blob/main/boolean.sql

 

 

Also read my previous blogs about Oracle Database 23:

And my next blog:

New PL/SQL iterator constructs

Kun je de vacature die je zoekt niet vinden?

Maak een Jobalert aan en ontvang een melding per mail
wanneer er nieuwe vacatures zijn!