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
Use an integer and just don't bother assigning anything other than 0 or 1 to it.
Use a char field with 'Y' or 'N' as the only two values.
Use an enum with the CHECK constraint.
Do experienced Oracle developers know which approach is preferred/canonical?
This question is related to
oracle
boolean
sqldatatypes
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.
The database I did most of my work on used 'Y' / 'N' as booleans. With that implementation, you can pull off some tricks like:
Count rows that are true:
SELECT SUM(CASE WHEN BOOLEAN_FLAG = 'Y' THEN 1 ELSE 0) FROM X
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.
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
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
.
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.
The best option is 0 and 1 (as numbers - another answer suggests 0 and 1 as CHAR for space-efficiency but that's a bit too twisted for me), using NOT NULL and a check constraint to limit contents to those values. (If you need the column to be nullable, then it's not a boolean you're dealing with but an enumeration with three values...)
Advantages of 0/1:
select sum(is_ripe) from bananas
instead of select count(*) from bananas where is_ripe = 'Y'
or even (yuk) select sum(case is_ripe when 'Y' then 1 else 0) from bananas
Advantages of 'Y'/'N':
Another poster suggested 'Y'/null for performance gains. If you've proven that you need the performance, then fair enough, but otherwise avoid since it makes querying less natural (some_column is null
instead of some_column = 0
) and in a left join you'll conflate falseness with nonexistent records.
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.
Source: Stackoverflow.com