Motorcure's Personal Blog

You Suffer,But Why...

首页 CNDEV 网志 联络 (RSS 2.0) (Atom) 登录
  随笔 140 :: 收藏 37 :: 评论 0 :: 寻迹: 0

随笔

随笔归档

收藏

图库

混迹江湖

礼尚往来

在设计数据库表结构时,选择一种高效的策略来存储一个可以在很多编程环境中使用的逻辑布尔值是非常重要的。(虽然 Oracle 没有 Boolean 数据类型来表示数据库字段,但是在 PL/SQL 中却具有 Boolean 数据类型。)

任何布尔定义的字段还应该被正确进行约束检查,以确保在插入/更新时输入了有效的值。

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

最常见的设计是模拟很多 Oracle 的数据字典视图中使用的类似布尔的标志,选择‘Y’表示真,‘N’表示假。然而,要正确地与宿主环境交互,比如与 JDBC、OCCI 和其它编程环境交互,最好选择0表示,选择1表示,从而使getBoolean 和setBoolean 能够正确地处理它们。

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.

我们可以将一个布乐类型定义为 NUMBER(1);然而,在 Oracle 的内部数字格式中,0在长度字节之后占用一个字节,而1在长度字节之后占用两个字节(所以更加高效地方式是将其存储为 CHAR)。即使字符被定义为 CHAR,SQL 也可以转换和验证实际的数字。

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

下面是一个 Java 例子:

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();
    }
}

此外,在 OCI、OCCI 和 PRO/C 中,如果选定值作为一个整数被请求(SQLT_INT 或 OCCIINT),它将会自动地由客户端程序库转换成二进制0或1,从而可以用作本地布尔值。

下面是以 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;
}

发表于 @ 2004-08-01 10:44

Feedback

尚无评论

发表评论

标题:  
署名:  
链接:
内容:
验证码: