Oracle Tip: Choosing an efficient design for Boolean column values
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的更多相关文章
- 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 = ...
- Oracle Applications Multiple Organizations Access Control for Custom Code
档 ID 420787.1 White Paper Oracle Applications Multiple Organizations Access Control for Custom Code ...
- 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 ...
- [转]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 ...
- Oracle EBS - Doc
Oracle EBS spec.: http://vianet/IT/IT%20Dept/IT%20Project%20Update2/Active%20Projects%20%20Manufactu ...
- sql boolean类型
关于 MySQL 的 boolean 和 tinyint(1) boolean类型MYSQL保存BOOLEAN值时用1代表TRUE,0代表FALSE,boolean在MySQL里的类型为tinyint ...
- Padding Oracle Attack的一些细节与实现
Padding Oracle Attack还是颇具威力的,ASP.NET的Padding Oracle Attack被Pwnie评为2010年最佳服务端漏洞之一.还是看 Juliano Rizzo a ...
- Oracle corrupt block(坏块) 详解
转自:http://blog.csdn.net/tianlesoftware/article/details/5024966 一. 坏块说明 1.1 相关链接 在看坏块之前,先看几个相关的链接,在后面 ...
- Oracle composite index column ordering
Question: I have a SQL with multiple columns in my where clause. I know that Oracle can only choos ...
随机推荐
- BOM之JavaScript常用事件
body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...
- java的代理(编程思想)
代理 第三种关系被称为代理,java并没有提供对它的直接支持.这是继承和组合之间的中庸之道,因为我们将一个对象置于所要构造的类中(就像组合),但与此同时我们在新类中暴露了该成员对象的所有方法(就像继承 ...
- Python基础学习----参数和返回值
# 函数的参数和返回值 # 4种组合方式 # 1.无参无返 # def methodone(): # 2.无参有返 def methodtwo(): a=10 return a # 3.有参无返 # ...
- 同时发出 ajax 拿到正确的返回值问题
方案 大概意思就是前端在data里面 传一个标示给后台, 后台再ajax返回的时候携带这个标示
- mongdb分布式
搭建高可用mongodb集群(一)——配置mongodb Posted on 17 十一月, 2013 by lanceyan | 21 Replies 在大数据的时代,传统的关系型数据库要能更高的服 ...
- ios系统降级
1.使用PP助手/iTunes备份好文件资料,以防重要信息丢失: 2.设备连接iTunes,按住Shift键之后点击“恢复iPhone”,选择已下载好的iOS8.4.1固件,等待更新完成即可. 注意要 ...
- CentOS怎样安装Python3.6
yum install -y openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-devel安装可能用到的依赖 ...
- 安装配置adb工具及遇到的问题
一. 下载安装 配置环境 二.遇到的问题 1.Terminal 不是内部或外部命令,也不是可运行程序或批处理文件 https://blog.csdn.net/wuqilianga/article/de ...
- 【idea】常用快捷键
快捷键盘含义 键组合 进入一个类的实现 alt+command+B 加get,set,构造函数,重写方法 command+N 全项目关键字查找 shift+command+F 查看一个类在哪儿被依赖 ...
- .NET实现WebSocket服务端即时通信实例
即时通信常用手段 1.第三方平台 谷歌.腾讯 环信等多如牛毛,其中谷歌即时通信是免费的,但免费就是免费的并不好用.其他的一些第三方一般收费的,使用要则限流(1s/限制x条消息)要么则限制用户数. 但稳 ...