分享

ODAC简介

 一岁两枯荣 2013-09-04

ODAC简介
http://www.360doc.com/mailto:nxyc_twz@163.com
ODAC(Oracle 数据存取组件)4.05 说明
Core Lab 保留所有版权  1997-2002.
--------------------------------------------------

Oracle 数据存取组件(ODAC) 库为Borland Delphi,C++ Builder 以及 Kylix提供了一些非可视化的组件。它们用来存取Oracle关系数据库系统。与BDE类似, ODAC 也是一种可供选择的处理数据的方法之一。

ODAC 直接使用 Oracle 调用接口 (OCI). OCI 是一种允许应用程序开发人员使用第三方开发语言存取Oracle数据服务器的过程或函数以及控制所有的SQL语句执行状态的应用程序接口(API)。OCI 通过一个动态运行库(ORA*.DLL)提供了一个标准的数据库存取库及函数,以在应用程序中建立连接。也可以使用ODAC的Net选项而无需在客户机上安装Oracle客户端来连接到Oracle.在这种情况下,ODAC仅需要TCP/IP协议的支持,从而可以创建真正的、最小的数据库应用程序。

与使用BDE开发 Oracle C/S(客户/服务器)应用程序不同的是,BDE不能存取Oracle的一些特殊功能,不能使用更多的资源,不能高速处理数据,而且不定期有麻烦的应用程序分发以及管理。

使用BDE存取Oracle的方式是:

[Oracle RDBMS] <> [SQL*Net] <> [OCI] <> [SQL Links] <> [BDE] <> [Application]

ODAC 直接使用 OCI。 它允许不使用 BDE 及 SQL Links:

[Oracle RDBMS] <> [SQL*Net] <> [OCI] <> [Application]

ODAC Net 提供了更好的方法:

[Oracle RDBMS] <> [TCP/IP] <> [Application]

ODAC 包含了以下组件:

TOraSession - 控制服务连接;
TOraQuery - 执行查询,操作记录集,灵活地更新数据库表;
TSmartQuery - 与 TOraQuery 功能类似,可自动创建 INSERT, DELETE, UPDATE 查询,自动锁定及更新记录;
TOraSQL - 执行SQL语句, PL/SQL 块,存储过程;
TOraPackage - 允许执行包中的过程及函数以及变量;
TOraTable - 允许不需要使用SQL语句来读取及更新单个表;
TOraStoredProc - 执行存储过程和函数,允许编辑游标并可作为参数返回;
TOraNestedTable - 控制嵌套表数据;
TOraProvider - 提供从客户数据集进行数据及应用更新;
TOraScript - 执行 SQL 及 PL/SQL 语句;;
TOraAlerter - 允许在两个会话中传送消息;
TOraLoader - 快速装载Oracle数据库;
TOraSQLMonitor - 允许监视执行基于ODAC应用程序中的动态SQL语句;
TOraErrorHandler - 传送错误信息;
TBDESession - 允许将ODAC集成到基于BDE的应用程序中;
TConnectDialog - 用来输入用户名,口令及服务名;
TCRDBGrid - 增强的 TDBGrid , 提供可视化的的数据过滤及增量查询;
TVirtualTable - 数据存储在内存中。

使用ODAC可以为你提供以下优势:

- 选择Net选项使客户机上不再需要安装 Oracle 客户端;
- 不需要分发,安装及配置 BDE 及 ODBC;
- 你可以使用任何 Delphi/C++ Builder 专业版来开发客户/服务器应用程序;
- 允许你使用许多 Oracle 的特殊功能;
- 支持 Oracle 8 的特殊特性: BLOB, CLOB 以及 BFile 数据类型,对象,数组,引用,嵌套表;
- 简化数据更新;
- 提供两种更新数据的方法:更灵活的 TOraQuery 及更容易的 TSmartQuery;
- 高速数据库记录存取;S
- 提供自动锁定及刷新记录机制;
- 允许通过使用多线程来执行长时间的存储过程;
- 高级设计编辑器;
- ODAC 组件的界面(方法,属性)和标准的BDE数据存取组件(TDatabase,TQuery,..)非常相似;
- 支持所有的数据集组件;
- 使用 OraTools 插件的OraDesigner建立和检查使用OraDesigner的查询,使用OraDebugger设计和调试PL/SQL块以及使用OraExplorer浏览数据库。


兼容性
-------------

ODAC 支持 Oracle 7.3, 8.0, 8i 以及 9i, 包括个人版及简装版。


安装
------------

自 ODAC 3.20 版以后,其运行包和设计包被分离了出来。ODAC 安装程序拷贝这些文件到其相应目录。

odacXX.bpl - ODAC 运行包 (位于 Windows\System 目录)
dclodacXX.bpl - ODAC 设计包 (位于 Delphi\Bin 目录)
odacvclXX.bpl - VCL 支持包 (位于 Delphi\Bin 目录)
oraprovXX.bpl - TOraProvider 组件 (位于 Delphi\Bin 目录)
crcontrolsXX.bpl - TCRDBGrid 组件 (位于 Delphi\Bin 目录)

Delphi
======

要编译基于ODAC的应用程序,需要在项目属性的 Project Options|Search 路径中添加 $(DELPHI)\ODAC\Lib。

C++ Builder
===========

要编译基于ODAC的应用程序,需要在项目属性的 Project Options|Library路径中添加 $(BCB)\ODAC\Lib,在 Project Options|Include 路径中添加 $(BCB)\ODAC\Include 。

Kylix
=====

首先你应该取得Kylix IDE 中的ODAC包,使用下面的命令将ODAC包的安装路径添加到指定路径:

PATH=$PATH:<ODAC directory>

另外的方法是将所有的 ODAC 包(*.so)拷贝到任意目录,比如 kylix/bin.现在你可以将ODAC安装到
Kylix IDE 中。请选择Kylix菜单 Component/Install Packages 。按添加按钮并选择 bpldclodacX.包。按OK按钮使组件有效。你也可以将 odac/lib添加到你项目的探索路径中。
TOraProvider 组件
======================

如果你使用企业版的 Delphi 或 C++ Builder,你可以单独安装 TOraProvider 组件。你要做的就是编译并安装 oraprovXX.bpk 包。

OraTools 插件
===============

自 ODAC 3.50 版以后,不再包含设计包 oratoolsXX.bpl. OraTools 现在被作为一个独立的插件来提供。它被安装一次即可在  Delphi 和 C++ Builder 下使用。但现在它还不支持 Kylix 。

使用ODAC的 GUI 编写应用程序
--------------------------
自ODAC 3.80 版以后, GUI 就成为了其标准部件之一。意思也就是说以下GUI元素有效:SQL游标,连接Form,连接对话框等。 你必须在你的应用程序中明确地声明头 OdacVcl (在Linux下是OdacClx ) 单元。这项功能对于在Linux下编写控制台应用程序特别有用。

Delphi and C++ Builder

By default ODAC does not require unit Forms, Controls and so on. Except
TOraErrorHandler and TConnectDialog components. They require unit Forms
and it's dependants by their nature.

Kylix

在默认情况下,ODAC并产需要QT库,但除了 TOraErrorHandler,TConnectDialog 以及 TOraAlerter组件以外。 它们包含了依赖于QT的代码。另外, SmartRefresh 功能禁止在 Kylix 下使用. 但是专业版用户可在Odac.inc中定义宏SMART_REFRESH来实现在Linux环境下SmartRefresh功能。默认情况下,SMART_REFRESH宏在Windows环境下被定义。但是 SmartRefresh 函数需要 QT.


预览版限制
--------------------------
下面的信息说明了在使用ODAC预览版时的限制:
- 只能在IDE环境中运行基于ODAC设计的应用程序
- 如果选择了 Net 选项,在TOraDataSet中仅能够最多使用6个字段。


在IDE中使用多个产品
---------------------------------
ODAC, SDAC 以及 MyDAC 组件使用公用包。
它们是:
dacXX.bpl
dacvclXX.bpl
dcldacXX.bpl
注意:这些产品只有同时被提供时才具有兼容性。如果你升级了已安装的产品的一部分,有可能会导致与其它部分发生冲突。为了继续同时使用这些产品,你应该同时升级它们。
联系方式:
--------------------
http://www./
http://www.360doc.com/mailto:nxyc_twz@163.com
ODAC使用指南
http://www.360doc.com/mailto:nxyc_twz@163.com

(一)ODAC常见问题集
________________________________________
" ODAC与BDE数据存取组件(BDE DAC)相比有什么优势?
             极高速的数据存取,这一点非常诱人。
     可以调节每个执行查询的参数,以优化索引"资源/生产"。
     可以终止长时间执行的查询(不幸的是,这项功能并不被ORACLE的PL-SQL块所支持)。
         完全支持PL-SQL。
     通过存储过程或匿名PL-SQL块(使用参数)得到游标。
     通过存储过程或匿名PL-SQL块得到PL-SQL表。 
     内建了不同的查询支持。
     内建了运行时调试系统。
     简单便利地使用已提供的标准的错误处理机制。
     将应用程序安装到其它计算机的过程非常简单,因为不需要安装和配置BDE。
" W使用ODAC编写的应用软件在客户机上运行时,需要哪些软件支持?
        要执行使用ODAC设计的应用程序,需要在客户机上安装ORACLE *SQL-NET2.3(ORACLE 7.3)或ORACLE NET8客户端。
" 我是否有权发布、传播用ODAC开发的应用程序?
     如果你购买了ODAC,你就有权利传播任何已编译的、使用ODAC设计的应用程序。但你没有权利传播任何继承自ODAC或使用ODAC源码的组件。你也可以查看License.txt文件。
" 我能否使用ODAC来创建新的组件?
     你可以通过继承ODAC或使用ODAC源码来创建你自己的组件. 你有权利传播和销售(已编译的窗体)自己设计的应用程序,比如组件,但不是组件自己。你可以查看License.txt文件。
     为了编译你创建在标准query组件之上的包,你需要ODAC的运行包ODAC.dcp。
" 我已经注册了ODAC的X.XX版。我是否需要为ODAC的后续版本付费?
      在你已经会费注册的情况下,如果ODAC的主版本与当前版本不同,你就需要再会费。比如, 从ODAC 1.70 升级到 ODAC 1.85 是免费的, 但升级 ODAC 2.00版则要收费。注册的价格是29美元,免费提供技术扶持。
" ODAC的源码中都包含了些什么?
      ODAC的源码包含ODAC除了SQL设计模块以外的所有模块的源码, SQL设计器以DCU文件的方式提供。SQL设计器仅是在ODAC设计过程中使用,因此就并需要它的源码。
" ODAC不支持BDE DAC的什么操作?
     ODAC不支持其它的数据系统,也不能创建多平台的应用程序。 
" ODAC 支持 Oracle 7.3 和 Oracle 8. ODAC是否可在以前的ORACLE版本使用?
      为了在ORACLE以前的版本上使用ODAC,需要在客户机上安装 Oracle 7.3和Oracle 8 的SQL-Net2.3。非常抱歉,如果已经安装了其它版本的 *SQL-Net ,所有的设置 (包括数据库别名)都将丢失。为了保存这些设置, 我们建议您重新安装(安装) 包含在 Oracle 7.3中的Oracle调用接口 , 以作为 Oracle *SQL-Net的替代品。 这样的更改将不影响任何其它已经安装的设置,这是实现ODAC功能所必须的。
" ODAC 支持 Oracle 7.3 和 Oracle 8. ODAC是否可在以前的ORACLE版本使用?
      为了在ORACLE以前的版本上使用ODAC,需要在客户机上安装 Oracle 7.3和Oracle 8 的SQL-Net2.3。非常抱歉,如果已经安装了其它版本的*SQL-Net ,所有的设置 (包括数据库别名)都将丢失。为了保存这些设置, 我们建议您重新安装(安装) 包含在Oracle 7.3中的Oracle调用接口 , 以作为Oracle *SQL-Net的替代品。 这样的更改将不影响任何其它已经安装的设置,这是实现ODAC功能所必须的。
" 为了将用BDE DAC创建的项目快速地改写为ODAC应用项目,必需做些什么?
应该按下面的步骤进行:The following steps should be made:
1. 删除所有 TSession 组件。
2. 执行下面的修改:
" 将TDataBase 控件改为 TOraSession
" 将TQuery控件改为 TOraQuery
" 将TStoredProc控件改为 TOraStoredProc
" 将TTable控件改为 TOraTable. 如果使用了 UpdateObject ,必须改变 TOraQuery, 在其SQL属性中写入: 
Select * from <TableName> [order by <IndexFieldNames>]
3. 对于 TUpdateSQL控件,我们分别将其 DeleteSQL, InsertSQL, ModifySQL内容写入到TOraQuery组件的 SQLDelete, SQLInsert, SQLModify 中。
" 一个大项目的一部分已经投入运行,是否能使用ODAC新建一个模块,通过这种方法使BDE DAC与ODAC共同工作?
     在同一个项目中同时使用ODAC与BDE DAC并没有什么限制。但是,我们有一个要求: ODAC 和 BDE DAC 必须使用不同的会话(sessions),原因如下:
" ODAC 和 BDE DAC 不能共享同一个事务
" 或许,必须增加会话数量才能得到服务器的支持。
为了避免这种情形的发生,应该添加 TBDESession 组件,以用来连接 Oracle。
" ODAC提供的调用调试和SQL操作执行以及PL-SQL指的是什么意思?
     ODAC 提供了两种额外的调试方法:设计时和运行时。SQL设计器,所有的ODAC数据集的组件编辑都继承于它,在设计时允许调试服务器:
" 执行SQL查询以及结果示范以及设计查询
" 用参数对PL-SQL块进行初始化以及在执行后返回参数值 
" 追踪PL-SQL块执行的内部过程。
" 断点设置
" 在PL-SQL执行时,返回变量的设置及变化值。
    ODAC数据集中的Debug属性被用来在运行期进行调试。如果ODAC数据集的这个属性被设置为 True,在查询或PL-SQL块执行时,将会显查询或块代码以及参数值信息。 
" TOraQuery, TSmartQuery 以及 TOraTable 有什么不同?
所有这些组件都继承自 TDataSet 并且拥有一些特性:
o TOraQuery 是执行数据查询和编辑最常见的方法,你可以决定任何SQL操作或执行PL-SQL块的记录插入、更新以及删除操作。在设计时,你可以使用TOraQueryEditor的SQL生成器帮助你生成DML操作语句,或使用存储过程生成器生成存储过程。 TOraQuery 实现了 ODAC数据集的所有功能。 TSmartQuery 和 TOraTable 可以减少编程设计时间。
o TSmartQuery 省了你进行数据更新及及生成DML的操作。一般地,在你应用程序中的大多数表应该使用它。 
o TOraTable 完全支持数据查询以及更新的SQL操作以及本地表操作. 只有表或视图名称是必需的要填写的。

 
" 我使用TSmartQuery不能成功获取可编辑的查询结果,但当使用TOraQuery时却可以。请问为什么会这样?
你必须明白,为了使任何数据集组件可以被编辑,就必须保证数据表中的记录允许被更新,并且能被独立识别。对TSmartQuery来说,它必须要在属性KeyFields中指出字段名,以标识记录(例如,字段,主键或唯一索引).
有一种可供选择的办法是 - 如果查询字段之一是更新表的RowId, TSmartQuery 就会找到它并在属性KeyFields为空时使用RowId来标识它。
属性 UpdatingTable 服务显示表将被更新(如果在查询中有许多表)。如果它的值为空,正在使用的表就会显示SQL操作的结果。 为了更好地对查询结果进行操作,建议应总是设置属性UpdatingTable。 
" 在不连接数据库时,我使用TDBGrid该怎样显示数据,程序窗体?
你可以使用 TVirtualTable 组件. 如果数据结构是已知的,就可在设计时使用字段编辑器来创建字段。 如果数据结构由应用程序执行时决定 ,则必须使用 AddField 方法. 应用程序能像对普通表那样使用数据填充 TVirtualTable .
你可以看这个位置的例子:
... \ODAC\Demos\VirtualTable\Vtable.dpr
" 从 1.80 版开始,当执行SQL操作时,如果没有改变数据库记录或改变了多个记录, ODAC-TOraQuery 开始显示错误 ("更新失败"), 在ODAC以前的版本中却从来都没有这样的错误提示。我自动去除这个错误?
在ODAC的1.80版本以后添加了这种特性是为了简化项目中从BDE升级到ODAC的事务处理。 BDE 的 TUpdateSQL 支持这种方法。为了不出现这个错误提示,必须将属性StrictUpdate的值设置为False.  非常抱歉,这是一个 public 属性,也就是说它的值可在运行时被修改。 
" 使用ODAC创建了应用程序,用户可在DBGrid中直接编辑记录。我怎样才能禁止用户的删除记录操作?
如果像TDataSet 那样使用 TOraQuery ,就可以非常简单地禁止记录的删除、插入以及更新操作。简单地清除相关属性(SQLDelete, SQLInsert,SQLUpdate). 这种方法并不适用于SQL操作或PL-SQL块。如果删除操作被禁止,原因可能是在DBGrid中执行了dgConfirmDelete选项,因为这个组件不能被 "guess", 所以导致删除操作被禁止。
" 用户必须要在DBGrid中可删除、插入以及编辑记录,但删除操作并不在DB中被实现。如果在TOraQuery中不填充 SQLDelete , 在 DBGrid 中就不允许删除操作。是否有方法可以越过这种限制?
方法非常简单,在 SQLDelete 中输入以下内容:
begin  Null;end;
使用同样的方法,可以允许记录的更新以及插入,用这种方法并不能更新实际的数据表。如果不需要在数据表中实现任何的更新操作,可以使用 LocalUpdates。
" 数据表的主键用sequence(序列)填充. 在客户应用程序中能否禁止这个键的意义,而不需要执行任何额外的查询?
如果你使用 Oracle7, 获取新键值唯一的方法是显式查询。将这个字段用数据库的触发器来替换可以完全解决这个问题。为了简化网络传输及输出时间,可以使用下面的SQLInsert的PL-SQL块来代替SQL操作:  
begin  Select <sequence_name>.NextVal into :Id from Dual;  Insert into <table_name> values (:Id, ?;end;
如果你使用 Oracle8, 你可以使用数据库触发器来替换掉原有的字段。我们用触发器更新字段值这种方法来完成更新SQL操作: 
Insert into <table_name> values (Null, ? returning Id into :Id
通过这种方法,在Oracle8中可用其明显的牲性来使用SQL操作设置它的值: 
Insert into <table_name> values (<sequence_name>.NextVal, ? returning Id into :Id
上面的所有方法、例子都是假定的,表的 <table_name> 有一个被称为主键的标识字段而且这个字段在放在表中的第一个位置。 
不要忘了将属性 ReturnParams 设置为 True. 否则客户应用程序 "将不能查看" 新值.
如果你使用 TSmartQuery 操作、编辑有触发器的表,填充或校正字段值。你可按下面的步骤操作: 
 
o 不要在属性KeyFields中指出能过触发器来更新的字段。
o 总是指示为 RefreshMode. 如果字段能用触发器进行更新, RefreshMode 应该是 rmAfterUpdate 或 rmAlways, 如果是插入则是 rmAfterUpdate 或 rmAlways, 如果是插入和更新,则仅需要 - rmAlways
对ODAC 1.80 版的 TSmartQuery 来说,转换添加机制是最常见的情形。
" 使用户用存储过程来进行数据更新。 除了输入参数以外,还是输出参数,例如,"State".我怎样处理输出参数? 
请看下面的例子:
1. 例如,属性SQL的内容如下:
Select * from <table_name>
write
Select 0 as State, T.* from <table_name>
很自然,这些字段对应用程序用户而言是不可见的。
2. 我们写了一过程调用属性 SQLInsert, SQLUpdate and SQLDelete, 例如:
begin  <insert_procedure> (State -> :State, ?;end;
3. 我们设置属性 ReturnParams 为 True
 
" 在使用 BDE DAC 时,我们在DataSet中设置了属性 CachedUpdates 以使用户可以随意更改数据。如果既不调用ApplyUpdates方法也不调用CancelUpdates方法,这些更改并不在数据表中立即实现。ODAC属性 LocalUpdates 已经被添加,设计实现了同样的功能。我们能用ODAC使用同样的机制吗?
你可以使用原来的机制。
" 我们的项目使用了 MIDAS-技术. 我们将ORACLE作为一个高级服务器使,中间层用BDE存取ORACLE,通过DCOM执行客户端与服务端的连接,而没有使用 BDE . 我们想在中间层中想使用BDE,但是却没有什么好办法。ODAC不支持 IProvider 接口,但客户端必须要通过这个接口来得到结果。 能否解决这个问题?
为了解决这个问题,可以使用 TOraProvider 组件.并不需要重写客户应用程序。我们将服务端的 BDE DAC 改为 ODAC.然后添加 TOraProvider 组件. 我们应该设置ODAC数据集的属性DataSet的值. 同时用TOraProvider组件来替换 IProvider组件。


使用 ODAC 的 Net 方式
http://www.360doc.com/mailto:nxyc_twz@163.com
大多数应用程序使用 OCI 的ODAC 标准方式来连接 Oracle 数据库服务器。这是使用第三方开发语言设计 Oracle 应用程序最常用的方法。 所有的 OCI 接口都作为内部库来使用,使得编译生成的应用程序非常小。但是,这需要在客户机上安装 Oracle 客户端软件,这使得安装和管理要花费额外的开销。 有时,安装 Oracle 客户端程序甚至是不可能的。 例如,如果你需要在远程计算机上设置你的应用程序,你不能提供特殊的文件支持。

ODAC Net 允许你的应用程序直接通过 TCP/IP 协议来连接 Oracle,而不需要 Oracle 客户端软件。运行使用 ODAC Net 的应用程序,仅需要有一个支持 TCP/IP 协议的操作系统。
使用 ODAC Net 连接 Oracle 服务器,你需要知道 Oracle 服务器的地址,监听端口号以及数据库实例名称。
在你的应用程序中使用 Net 选项前,你只需要设置 TOraSession 对象的选项 Net 为 True 且指定它的Server 属性为指定的数据库。如果使用 ODAC 的标准方式通过 OCI 来连接数据库,你必须设置 Server 属性为 TNS 别名,但现在使用 ODAC 的 Net 选项,你只需要指定数据库字符串,格式如下: Host:Port:SID.

这里, Host 指服务器地址, Port 指服务器监听端口号, SID 指特定的系统实例名称。

这里有个例子示范不使用 OCI 而 连接数据库:

var
Session: TOraSession;
. . .
Session.Options.Net := True;
Session.Username := 'Scott';
Session.Password := 'tiger';
Session.Server := '205.227.44.44:1521:orcl';
Session.Connect;

注意:这些是你的应用程序要支持 Net 选项时所必须的。你不需要重写应用程序的其它部分。除此之外,你还可以在任何时候通过 OCI 连接 Oracle 。要实现它,你仅需要设置 TOraSession.Options.Net 选项为 False.

OCI 与 Net:
使用 ODAC 标准方式和 Net 方式编译的应用程序,在程序大小和运行速度上非常相似。使用 Net 选项在安全方面,与使用 OCI 的 Oracle 的加密方式并不相同。 Net 使用 DES 来验证安全性,现在它并不支持 Oracle 的加密方式。
ODAC Net 的优势:
- 不需要安装和管理 Oracle 客户端软件;
- 减少系统需求。

ODAC Net 选项的限制:

仅支持通过 TCP/IP 协议来连接 Oracle;
不支持 Oracle 8 的对象,数组;
不支持 TOraLoader 的直接装载;
请注意:我们并不能保证 ODAC Net 可以在所有网络上的所有 Oracle 服务器上运行。我们使用 Net 选项在本地局域网上测试了 Windows 平台上 Oracle 7.3 以后的所有版本。
ODAC 通过 OCI 可以运行在所有的 Oracle 服务器上。Net 选项在 Window 及 Linux 平台上的所有Oracle 服务器上被测试过。我们不能保证它可以运行在其它平台上。

使用防火墙时可能会出现验证问题。
Net 选项在本地语言下运行时会有些不同。它不支持客户端的 NLS 转换。
BreakExec 过程不能运行。
TOraLoader 组件不在运行在直接路径接口模式(lmDirect 模式)。

Net 选项还有一些其它问题。例如,进行截断日期比较时会出现错误。

SELECT * FROM scott.emp WHERE hiredate >= TRUNC(:hiredate)

执行该查询时会出现 ORA-00932 错误: 不支持的数据类型。

如果没有上面的限制,你可以通过 OCI 在任何时间关闭连接。

使用 BLOB 及 CLOB 数据类型
http://www.360doc.com/mailto:nxyc_twz@163.com
ODAC 组件支持 Oracle 8 的 BLOB 和 CLOB 数据类型。你可以使用 TOraQuery 组件来获取 LOB 字段的值,使用同样的方法,你也可以获取  LONG 或 LONG ROW 字段。 当你需要使用 SQL DML 及 PL/SQL 语句存取这些字段时,你就会发现 LOB 数据类型的用法有明显的不同。
BLOB 和 CLOB 数据类型通过 LOB 定位器(指定数据地址) 存储在表列中;实际的 BLOB 和 CLOB 数据存储在独立的表空间中。与之不同的是,LONG 或 LONG RAW 类型存储在数据库中,表中存放着它们的实际值。

当存取 LOB 列时,返回的是定位器,而不像 LONG 或 LONG RAW 数据类型那样返回它的实际值。
例如,分析这个表的定义:

CREATE TABLE ClobTable (
Id NUMBER,
Name VARCHAR2(30),
Value CLOB
)

如果我们不通过值参数初始化 LOB 定位器, Oracle 将不允许使用下面的语句来更新数据表:

UPDATE ClobTable
SET
Name = :Name,
Value = :Value

WHERE
Id = :Id

要初始化 LOB 定位器,你必须使用 EMPTY_BLOB 或 EMPTY_CLOB Oracle 函数。要返回初始化后的定位器,应在同样的语句中使用 RETURNING 子句。例如:

UPDATE ClobTable
SET
Name = :Name,
Value = EMPTY_CLOB()
WHERE
Id = :Id
RETURNING
Value
INTO
:Value

ODAC 写 LOB 数据到 Oracle 且返回初始值字段,需使用:值参数。
存储过程允许自动初始化 LOB 值,方法如下:

CREATE OR REPLACE
PROCEDURE ClobTableUpdate (p_Id NUMBER, p_Name VARCHAR2,
p_Value OUT CLOB)
is
begin
UPDATE ClobTable
SET
Name = p_Name,
Value = EMPTY_CLOB()
WHERE
Id = p_Id
RETURNING
Value
INTO
p_Value;
end;

注意:值参数被声明为 OUT。同时,设置 LOB 数据类型的参数的 ParamType 属性为 ptInput ,且指定它到所需的数据前来实际调用存储过程。我们可以这样调用前面声明的存储过程:

OraStroredProc1.StoredProcName := 'ClobTableUpdate';
OraStroredProc1.Prepare;
OraStroredProc1.ParamByName('p_Id').AsInteger := Id;
OraStroredProc1.ParamByName('p_Name').AsString := Name;
OraStroredProc1.ParamByName('Value').ParamType := ptInput;
OraStroredProc1.ParamByName('Value').AsCLOBLocator.
LoadFromFile(FileName);
OraStroredProc1.Execute;

对 ODAC 来说,在 LOB 操作中使用 ParamType 属性是非常重要的。如果 ParamType 是 ptInput , ODAC 写数据到服务器,如果 ParamType 是 ptOutput,它则读取数据。

你可以使用 LOB 参数的 dtBlob 和 dtMemo 数据类型来编写普通的 DML 语句。在这种情况下, Oracle 自动将 LONG 和 LONG ROW 类型的值转换为 CLOB 或 BLOB 数据。

主/明细表
http://www.360doc.com/mailto:nxyc_twz@163.com
两个表之间的主/明细表关系应用非常广泛。因此为数据库应用程序开发人员提供简单的方法来实现它是非常重要的。让我们看看如何实现这项功能。
假如我们在 "Department" 和 "Employee" 之间建立了主/明细表关系。"Department" 表包含以下字段: DepNo, DepName 和 Location。 DepNo 是一个数字型的主键,其它两个字段是字符串类型。
"Employee" 表包含以下字段: EmpNo, EmpName, Job, Manager 和 DepNo。 EmpNo 和 DepNo 是数字型字段, EmpName 和 Job 是字符串型字段。 EmpNo 是一个主键且 DepNo 是一个绑定 "Employee" 和 "Department" 的外键。

这是显示和编辑数据表所必需的。
ODAC 提供了两种绑定数据表的方法。第一个代码例子显示了通过参数绑定两个 TOraDataSet 组件 (TOraQuery, TSmartQuery, TOraTable 或 TOraStoredProc) 到主/明细关系中。

procedure TForm1.Form1Create(Sender: TObject);
var
Master, Detail: TOraQuery;
MasterSource: TDataSource;
begin
// 创建主数据集
Master := TOraQuery.Create(Self);
Master.SQL.Text := 'SELECT * FROM Department';

// 创建明细数据集
Detail := TOraQuery.Create(Self);
Detail.SQL.Text := 'SELECT * FROM Employee WHERE DepNo = :DepNo';

// 主表通过 TDataSource 组件来连接明细表
MasterSource := TDataSource.Create(Self);
MasterSource.DataSet := Master;
Detail.MasterSource := MasterSource;

// 打开主数据集和明细数据集
Master.Open;
Detail.Open;
end;

注意一件事情:明细数据集的SQL语句中的参数名必须等于主数据集中用作明细表外键的字段名。在打开明细表数据集后,其数据总是等于当前主数据集记录字段(比如 DepNo)所限定的值。
有一个额外的功能:当向明细表数据集插入新记录时,它自动从主表中获取相应值来填充其外键的值。
现在,假如明细表 "Department" 的外键被命名为 DepLink 而不是 DepNo. 在这种情况下,上面的代码例子中当插入记录时,明细表数据集将不会自动填充当前的 DepNo 到当前的 DepLink 字段。这个问题可以用第二个代码例子来解决:

procedure TForm1.Form1Create(Sender: TObject);

var
Master, Detail: TOraQuery;
MasterSource: TDataSource;
begin
// 创建主数集
Master := TOraQuery.Create(Self);
Master.SQL.Text := 'SELECT * FROM Department';

// 创建明细数据集
Detail := TOraQuery.Create(Self);
Detail.SQL.Text := 'SELECT * FROM Employee';

// 设置主/明细表
Detail.MasterFields := 'DepNo'; // primary key in Department
Detail.DetailFields := 'DepLink'; // foreign key in Employee

// 主表通过 TDataSource 组件连接明细表

MasterSource := TDataSource.Create(Self);
MasterSource.DataSet := Master;
Detail.MasterSource := MasterSource;

// 打开主数据表和明细表
Master.Open;
Detail.Open;
end;

在这个代码例子中,使用 MasterFields 和 DetailFields 属性建立主/明细关系。注意:在明细表的SQL语句中不能有 WHERE 子句。
ODAC 使用技巧 (四)使用VARRAY数据类型
http://www.360doc.com/mailto:nxyc_twz@163.com
   在使用对象时建议使用数组。但在你需要在数据集中使用大数组时可能会出现一些问题。比如,当为 ODAC 的一个字段创建大量数组时,也会创建大量的 TField 字段,这会导致程序的性能大大降低。 因此, ODAC 限制仅能为字段创建 1000 个成员。 但不管怎样,你都可以使用 TOraArray 对象来存取所有的成员。 当然,你也可以通过其它方法来实现。比如,设置 TOraQuery.SparseArray 为 True 并且通过 TArrayField 对象来存取数组成员。

如果创建了下面的类型:

CREATE TYPE TODACArray1 AS VARRAY (5) OF NUMBER;

CREATE TYPE TODACArray2 AS VARRAY (4) OF CHAR(10);

CREATE TABLE ODAC_Array (
Code NUMBER,
Title VARCHAR2(10),
Arr1 TODACArray1,
Arr2 TODACArray2,
);

要存取数组成员,你需要调用方法 FieldByName 。例如:

Value := Query.FieldByName('Arr1[0]').AsInteger;

If ObjectField property is True this code is right

Value := TArrayField(Query.FieldByName('Arr1')).Fields[0].AsInteger;

Using TOraDataSet.GetArray you can access to array items through TOraArray object

Value:= Query.GetArray('Arr1').ItemAsInteger[0];

你能够在 SQL 以及 PL/SQL 语句使用使用 VARRAY 类型作为参数。你需要指定 dtArray 到 TOraParam.DataType 并且使用 TOraParam.AsArray 属性来存取数组成员。
例如:

var
OraSQL: TOraSQL;
. . .
OraSQL.SQL.Text := 'INSERT INTO ODAC_Array (Code, Arr1, Arr2)' +
'VALUES (:Code, :Arr1, :Arr2)';

OraSQL.ParamByName('Code').AsInteger := 10;

with OraSQL.ParamByName('Arr1').AsArray do begin
AllocObject(OraSession.OCISvcCtx, 'TODACArray1');
ItemAsInteger[0] := 12;
AttrAsInteger['[1]'] := 10;
ItemAsInteger[3] := 133;
end;

with OraSQL. ParamByName('Arr2').AsArray do begin
OCISvcCtx:= OraSession.OCISvcCtx;
AllocObject('TODACArray2');
AttrAsString['[2]']:= 'eeee';
ItemAsString[0]:= 'FFFFF';
end;

OraSQL.Execute;

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多