Boolean Field in Oracle

Viewed 210004

Yesterday I wanted to add a boolean field to an Oracle table. However, there isn't actually a boolean data type in Oracle. Does anyone here know the best way to simulate a boolean? Googling the subject discovered several approaches

  1. Use an integer and just don't bother assigning anything other than 0 or 1 to it.

  2. Use a char field with 'Y' or 'N' as the only two values.

  3. Use an enum with the CHECK constraint.

Do experienced Oracle developers know which approach is preferred/canonical?

8 Answers

I found this link useful.

Here is the paragraph highlighting some of the pros/cons of each approach.

The most commonly seen design is to imitate the many Boolean-like flags that Oracle's data dictionary views use, selecting 'Y' for true and 'N' for false. However, to interact correctly with host environments, such as JDBC, OCCI, and other programming environments, it's better to select 0 for false and 1 for true so it can work correctly with the getBoolean and setBoolean functions.

Basically they advocate method number 2, for efficiency's sake, using

  • values of 0/1 (because of interoperability with JDBC's getBoolean() etc.) with a check constraint
  • a type of CHAR (because it uses less space than NUMBER).

Their example:

create table tbool (bool char check (bool in (0,1));
insert into tbool values(0);
insert into tbool values(1);`

Oracle itself uses Y/N for Boolean values. For completeness it should be noted that pl/sql has a boolean type, it is only tables that do not.

If you are using the field to indicate whether the record needs to be processed or not you might consider using Y and NULL as the values. This makes for a very small (read fast) index that takes very little space.

To use the least amount of space you should use a CHAR field constrained to 'Y' or 'N'. Oracle doesn't support BOOLEAN, BIT, or TINYINT data types, so CHAR's one byte is as small as you can get.

Either 1/0 or Y/N with a check constraint on it. ether way is fine. I personally prefer 1/0 as I do alot of work in perl, and it makes it really easy to do perl Boolean operations on database fields.

If you want a really in depth discussion of this question with one of Oracles head honchos, check out what Tom Kyte has to say about this Here

The database I did most of my work on used 'Y' / 'N' as booleans. With that implementation, you can pull off some tricks like:

  1. Count rows that are true:
    SELECT SUM(CASE WHEN BOOLEAN_FLAG = 'Y' THEN 1 ELSE 0) FROM X

  2. When grouping rows, enforce "If one row is true, then all are true" logic:
    SELECT MAX(BOOLEAN_FLAG) FROM Y
    Conversely, use MIN to force the grouping false if one row is false.

A working example to implement the accepted answer by adding a "Boolean" column to an existing table in an oracle database (using number type):

ALTER TABLE my_table_name ADD (
my_new_boolean_column number(1) DEFAULT 0 NOT NULL
CONSTRAINT my_new_boolean_column CHECK (my_new_boolean_column in (1,0))
);

This creates a new column in my_table_name called my_new_boolean_column with default values of 0. The column will not accept NULL values and restricts the accepted values to either 0 or 1.

In our databases we use an enum that ensures we pass it either TRUE or FALSE. If you do it either of the first two ways it is too easy to either start adding new meaning to the integer without going through a proper design, or ending up with that char field having Y, y, N, n, T, t, F, f values and having to remember which section of code uses which table and which version of true it is using.

Related