[oracle] Boolean Field in Oracle

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?

This question is related to oracle boolean sqldatatypes

The answer is


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:

  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.


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:

  • Language independent. 'Y' and 'N' would be fine if everyone used it. But they don't. In France they use 'O' and 'N' (I have seen this with my own eyes). I haven't programmed in Finland to see whether they use 'E' and 'K' there - no doubt they're smarter than that, but you can't be sure.
  • Congruent with practice in widely-used programming languages (C, C++, Perl, Javascript)
  • Plays better with the application layer e.g. Hibernate
  • Leads to more succinct SQL, for example, to find out how many bananas are ready to eat 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':

  • Takes up less space than 0/1
  • It's what Oracle suggests, so might be what some people are more used to

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.


Examples related to oracle

concat yesterdays date with a specific time ORA-28001: The password has expired how to modify the size of a column How to create a blank/empty column with SELECT query in oracle? Find the number of employees in each department - SQL Oracle Query to display all tablespaces in a database and datafiles When or Why to use a "SET DEFINE OFF" in Oracle Database How to insert date values into table error: ORA-65096: invalid common user or role name in oracle In Oracle SQL: How do you insert the current date + time into a table?

Examples related to boolean

Convert string to boolean in C# In c, in bool, true == 1 and false == 0? Syntax for an If statement using a boolean Truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all() Ruby: How to convert a string to boolean Casting int to bool in C/C++ Radio Buttons ng-checked with ng-model How to compare Boolean? Convert True/False value read from file to boolean Logical operators for boolean indexing in Pandas

Examples related to sqldatatypes

What does it mean when the size of a VARCHAR2 in Oracle is declared as 1 byte? How to get a list column names and datatypes of a table in PostgreSQL? How to display two digits after decimal point in SQL Server Conversion failed when converting the varchar value to data type int in sql Best data type to store money values in MySQL How to convert Nvarchar column to INT MySql: Tinyint (2) vs tinyint(1) - what is the difference? Is there any boolean type in Oracle databases? Appropriate datatype for holding percent values? How do you create a yes/no boolean field in SQL server?