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 ...
随机推荐
- 带你走进脚本世界,ijkplayer之【init-ios.sh】脚本分析
前言 集成ijkplayer,需要执行脚本init-ios.sh,那么init-ios.sh脚本干嘛用的了,花了半天时间,学习了下shell脚本,感觉脚本语言学起来还是比较容易上手的,现在仅仅能看懂了 ...
- PHP:第六章——正则表达式的基本概念
<?php header("Content-Type:text/html;charset=utf-8"); //正则表达式的基本概念: //宽松匹配和严格匹配: //常见的匹 ...
- qt忙等与非忙等
非忙等: void delay(int msec) { QTime end = QTime::currentTime().addMSecs(msec); while( QTime::currentTi ...
- 《转》深入理解Activity启动流程(二)–Activity启动相关类的类图
本文原创作者:Cloud Chou. 出处:本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 在介绍Activity的详细启动流程之前,先为大家介绍Act ...
- ArrayAdapter的用法
list = new ArrayList<String>(); //创建一个list list.add("ID列表"); //列表里面的条目 /*ArrayAdapte ...
- window XP下 php5.5+mysql+apache2+phpmyadmin安装
学了将近大半年的php了,还没有装过独立的php环境,一直用的集成的.记得刚学时,一头雾水,不知改怎么搭配环境,就觉得特别复杂,各种看不懂,今天还是自己在XP环境下搭配了一个. 首先,下载php5.5 ...
- LOJ2316. 「NOIP2017」逛公园【DP】【最短路】【思维】
LINK 思路 因为我想到的根本不是网上的普遍做法 所以常数出奇的大,而且做法极其暴力 可以形容是带优化的大模拟 进入正题: 首先一个很显然的思路是如果在合法的路径网络里面存在零环是有无数组解的 然后 ...
- yarn import 使用package-lock.json
yarn 1.7(目前最新的版本)支持npm 的package-lock.json 了 环境准备 安装更新yarn sudo npm install -g yarn 查看版本 yarn version ...
- 机器学习 ----Tensorflow
机器学习笔记4-Tensorflow线性模型示例及TensorBoard的使用 机器学习笔记3-Tensorflow简介 机器学习笔记2 – sklearn之iris数据集 机器学习笔记1 - Hel ...
- FastAdmin 开发时如何与官方同步升级
FastAdmin 开发时如何与官方同步升级 使用 FastAdmin 开发时为了与官方同步升级,推荐使用 git 管理代码. 官网上提供的完整包是为了方便第一次使用的人快速测试. 我一般是给官方的 ...