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 ...
随机推荐
- Intellij Idea 将java项目打包成jar
1.菜单:File->project stucture 2.在弹窗最左侧选中Artifacts->"+",选jar,选择from modules with depend ...
- idea里面Java文件显示一个x
idea里面Java文件显示一个x,编译时过滤了,setting->builder->compiler->excludes
- Cobbler自动化安装
# Cobbler自动化安装 [Cobbler官网](http://cobbler.github.io) 环境上. 运行 java -jar hello.jar 后结果如下(这里项目对外提供的端口是90 ...
- 【linux】查看进程
查询所有:ps aux 查询某个用户:ps -u abc 终止某个进程:kill
- Transaction ACID (转载)
Transaction 原文出处: 黄勇 Transaction 也就是所谓的事务了,通俗理解就是一件事情.从小,父母就教育我们,做事情要有始有终,不能半途而废.�0�2事务也是这样,不能做一般 ...
- C# #if, #else和#endif预处理指令
#if 使您可以开始条件指令,测试一个或多个符号以查看它们是否计算为 true.如果它们的计算结果确实为true,则编译器将计算位于 #if 与最近的 #endif 指令之间的所有代码.例如, ...
- 关于cookie和session的使用和理解
由于项目需要,最近用session容器比较多,传载的同时加上了自己的一些理解,不足之处还请大家补充和纠正. 一.cookie机制和session机制的区别 ********************** ...
- Packer 基本试用
安装 使用mac 系统 https://www.packer.io/downloads.html 配置环境变量 可选 sudo nano ~/.bash_profile export PATH=$PA ...
- Autocad 2010+ObjectArx 2010 +Vs2010 的.net 开发设置(转)
Autocad 2010+ObjectArx 2010 +Vs2010 的.net 开发设置 分类: ObjectArx.net2010-09-14 16:52 4203人阅读 评论(7) 收藏 举报 ...