Takeaway: When designing a database table structure, it's important to choose an efficient strategy for storing a logical Boolean that you can use in many programming environments. Find out how from this Oracle expert.

When designing a database table structure, it's important to choose an efficient strategy for storing a logical Boolean that you can use in many programming environments. (Although Oracle doesn't come with a Boolean datatype for database columns, it does have a Boolean datatype in PL/SQL.)

Any Boolean-defined column should also be properly constrained by checks to make sure that only valid values are entered at insert/update time.

create table tbool (bool char check (bool in ('N','Y'));
insert into tbool values ('N');
insert into tbool values ('Y');

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.

We could define a Boolean as NUMBER(1);
however, in Oracle's internal number format, 0 takes 1 byte and 1
takes 2 bytes after the length byte (so it's more efficient to
store it as CHAR). Even though the character is defined as CHAR,
SQL can convert and verify against actual numbers.

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

Here is a Java example:

import java.sql.*;

public class bool
{
    public static void main(String[] args)
throws SQLException
    {
        try
        {
           
Class.forName("oracle.jdbc.driver.OracleDriver");
        }
        catch
(ClassNotFoundException e)
        {
            System.out.println("error:
driver not in CLASSPATH");
            return;

}
        Connection conn =
DriverManager.getConnection(
           
"jdbc:oracle:oci8:@","scott","tiger");
        Statement stmt =
conn.createStatement();
        ResultSet rset =
stmt.executeQuery("select bool from tbool");
        Boolean
bool;
        while
(rset.next())
        {
            if
(rset.getBoolean(1))
               
System.out.println("bool is true");
            else
System.out.println("bool is false");
        }
        rset.close();

stmt.close();

conn.close();

}
}

Also, in OCI, OCCI, and PRO/C, if the selected
value is requested as an integer (SQLT_INT or OCCIINT), it will
automatically convert into binary 0 or 1 by the client-side
libraries, which can be used as native Boolean values.

Here is the same sample in OCCI:

#include <string>
#include <iostream>
#include <occi.h>
using namespace oracle::occi;
using namespace std;

int main(int argc,char* argv[])
{
    bool b;
    Environment* env =
Environment::createEnvironment();
    try
    {
        Connection* conn =
env->createConnection("scott","tiger");
        Statement* stmt =
conn->createStatement("select bool from tbool");
        ResultSet* rset =
stmt->executeQuery();
        rset->setDataBuffer(1,&b,OCCIINT,sizeof(bool));

while
(rset->next())
        {
            if
(b) cout << "bool was true" << endl;
            else
cout << "bool was false" << endl;
        }
        stmt->closeResultSet(rset);

conn->terminateStatement(stmt);
        env->terminateConnection(conn);

}
    catch (SQLException e)
    {
        cout <<
e.what() << endl;
    }
    Environment::terminateEnvironment(env);
    return 0;
}

By using setDataBuffer with a C++ bool value,
the correct integer value gets bound to a C++ bool. Unfortunately,
there's no getBoolean in OCCI. Therefore, it may be more portable
to use an int or char, or use rset->getInt(1) instead
of binding. (Note: In my tests, there is apparently a bug in OCCI
where using getInt(1) on a CHAR column failed unless I used
to_number(bool) or bool+0.)

When creating a Boolean data column, you should
be careful to make sure that the column is properly "nullable." If
a column with two possible values isn't constrained with NOT NULL,
then you're allowing three possible values: true, false, and unknown. This is often not
what is intended and host languages environments must deal with the
possibility that NULL is returned. Either 2-value or 3-value may be
acceptable in certain circumstances. This SQL restricts a BOOLEAN
value to 2-values only:

create table tbool (bool char not null check (bool
in (0,1));

However, Oracle SQL still requires a condition
operator, so there's no way to get around testing for the actual
value being 1 or 0, although you can hide these values in a
standardization package. For instance, see how I can reuse/expose
the keywords true and false through a PL/SQL
package:

create or replace package bool
as
    subtype bool is char;
    function false return bool;
    function true return bool;
    function val(b bool) return
varchar2;
end bool;
/
show error

create or replace package body bool
as
    function false return bool
    is
    begin
        return 0;
    end false;
    --
    function true return bool
    is
    begin
        return 1;
    end true;
    --
    function val(b bool) return varchar2
    is
    begin
        if b = true
then
            return
'true';
        end if;
        return
'false';
    end val;
end bool;
/
show error

insert into tbool values(bool.false);
insert into tbool values(bool.true);

select bool.val(bool) from tbool where bool = bool.true;

Oracle Tip: Choosing an efficient design for Boolean column values的更多相关文章

  1. Digital design之Boolean Algebra

    1. 0 and 1 (duality: 0 -- 1, · -- +) X + 0 = X, X · 1 = X X + 1 = 1, X · 0 = 0 2. Idempotent X + X = ...

  2. Oracle Applications Multiple Organizations Access Control for Custom Code

    档 ID 420787.1 White Paper Oracle Applications Multiple Organizations Access Control for Custom Code ...

  3. oracle已知会导致错误结果的bug列表(Bug Issues Known to cause Wrong Results)

    LAST UPDATE:     1 Dec 15, 2016 APPLIES TO:     1 2 3 4 Oracle Database - Enterprise Edition - Versi ...

  4. [转]Using the Microsoft Connector for Oracle by Attunity with SQL Server 2008 Integration Services

    本文转自:http://technet.microsoft.com/en-us/library/ee470675(v=sql.100).aspx SQL Server Technical Articl ...

  5. Oracle EBS - Doc

    Oracle EBS spec.: http://vianet/IT/IT%20Dept/IT%20Project%20Update2/Active%20Projects%20%20Manufactu ...

  6. sql boolean类型

    关于 MySQL 的 boolean 和 tinyint(1) boolean类型MYSQL保存BOOLEAN值时用1代表TRUE,0代表FALSE,boolean在MySQL里的类型为tinyint ...

  7. Padding Oracle Attack的一些细节与实现

    Padding Oracle Attack还是颇具威力的,ASP.NET的Padding Oracle Attack被Pwnie评为2010年最佳服务端漏洞之一.还是看 Juliano Rizzo a ...

  8. Oracle corrupt block(坏块) 详解

    转自:http://blog.csdn.net/tianlesoftware/article/details/5024966 一. 坏块说明 1.1 相关链接 在看坏块之前,先看几个相关的链接,在后面 ...

  9. Oracle composite index column ordering

    Question:  I have a SQL with multiple columns in my where clause.  I know that Oracle can only choos ...

随机推荐

  1. 如何处理HTML5新标签的兼容性问题

    支持HTML5新标签: * IE8/IE7/IE6支持通过document.createElement方法产生的标签, 可以利用这一特性让这些浏览器支持HTML5新标签, 浏览器支持新标签后,还需要添 ...

  2. mysql "Your password has expired...."错误解决方案

    mysql -u root -p 进入mysql命令界面,然后输入 set password = password("新密码"); 参考:http://blog.csdn.net/ ...

  3. generator.xml文件与相关配置插件

    一,generator.xml配置信息 1 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ...

  4. 华为荣耀7i手动更改DNS,提高网页加载速度

    为什么在同样的Wi-Fi网络下,别人的手机可以秒开网页,但自己的手机却总会慢个半拍或是经常打不开,简直龟速.有时还会加载网页失败.我想大部分人都遇到过吧. 今天本人给大家介绍一种方法,可以加快打开网页 ...

  5. ES6必知必会 (八)—— async 函数

    async 函数 1.ES2017 标准引入了 async 函数,它是对 Generator 函数的改进 , 我们先看一个读取文件的例子: Generator 写法是这样的 : var fs = re ...

  6. Python协程 Gevent Eventlet Greenlet

    https://zh.wikipedia.org/zh-cn/%E5%8D%8F%E7%A8%8B 协程可以理解为线程中的微线程,通过手动挂起函数的执行状态,在合适的时机再次激活继续运行,而不需要上下 ...

  7. nats 学习 request/reply 模式基本使用

    nats 一个云原生的消息系统,使用简单,客户端丰富,支持的模式是pub/sub 但是集成比较灵活,可以支持loadblance, request/reply pub/sub 代码演示的是reques ...

  8. oracle 查版本号

    oracle是强大的数据库,我们怎样看它的版本呢? 工具/原料 oracle 数据库, sqlplus 方法/步骤 首先进入sqlplus,cmd---plsql,登陆我们的用户,如:user/pas ...

  9. php 文件上传$_FILES中error返回值详解

    用PHP上传文件时,我们会用程序去监听浏览器发送过来的文件信息,首先会通 过$_FILES[fieldName]['error']的不同数值来判断此欲上传的文件状态是否正常.$_FILES[field ...

  10. kettle modified javascript 步骤的一个例子

    例子里用到的 org.htmlparser.Parser 是一个html 的解析器,可以在 sourceforge 上下载. 这个例子使用 org.htmlparser.Parser 包来解析一个 h ...