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 ...
随机推荐
- HALCON之喷码OCR识别案例
一个喷码识别的案例 1 read_image (Image, 'D:/用户目录/Desktop/2.png') 2 3 rgb1_to_gray(Image, Image) 4 5 get_image ...
- windows下搭建nginx+php+虚拟主机配置过程
需要软件信息: nginx php RunHiddenConsole 首先安装之前要规划一下把他们放到那里,比如我将他们统一放在e :/web下 那么将这些都拷贝过来,开始吧,window要执行php ...
- 201621123006 《Java程序设计》第9周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 本次作业题集集合 List中指定元素的删除(题集题目) 1.1 实验总结.并回答:列举至少2种 ...
- WebGL编程指南案例解析之绘制一个点
<!DOCTYPE html> <html> <head> <title>webgl</title> <style type=&quo ...
- Ubuntu系统安装,适用于14.04,16.04和17.10
本文以14.04为案例进行安装,其他版本相关问题会做注解 1.选择要安装的系统语言 本界面建议选择English,之后再选择中文安装 注意: 安装服务器版时,对于14.x版本第一步选择中文没有问题,但 ...
- 中国的 Python 量化交易工具链有哪些
摘抄自知乎:https://www.zhihu.com/question/28557233 如题,提问的范围限于适合中国大陆金融市场使用的工具链,所以IbPy和Quotopian之类主要面向欧美市场的 ...
- Java第五次作业--面向对象高级特性(抽象类和接口)
一.学习要点 认真看书并查阅相关资料,掌握以下内容: 掌握抽象类的设计 掌握接口的设计 理解简单工厂设计模式 理解抽象类和接口的区别 掌握包装类的应用 掌握对象的比较方法和比较器的使用 学习使用日期操 ...
- Python ImportError: No module named Image
/********************************************************************************* * Python ImportEr ...
- HDU - 4676 :Sum Of Gcd (莫队&区间gcd公式)
Given you a sequence of number a 1, a 2, ..., a n, which is a permutation of 1...n. You need to answ ...
- C# 实现网络时间同步功能
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...