UniDAC使用日记
四年级 日记 13710字 4975人浏览 倚天屠龙637

UniDAC 使用日记

1. UniQuery默认状态为行提交,使用前根据需要设置readonly 或cachedupdates 属性

2. UniQuery.Filter默认大小写区分,请注意设置FilterOptions 属性([foCaseInsensitive]),TVirtualtable 也存在相同情况

3. UniQuery默认情况下,有些varchar 类型的字段有自动加了一个空格,请注意设置Options.TrimVarChar=true

4. UniQuery在进行Insert 时,若字段不能为null 且前台操作未填写时,可能会报错,请设置RequiredFields=true

5. UniQuery在修改数据集时,默认的方式是按关键字生成SQL 语句进行数据提交。还有另外两种方式:一是设置updateSQL ,一是设置KeyFields (具体请sql 跟踪查看)

6. UniQuery的数据排序属性是IndexFieldNames

7. 数据提交的顺序,一定要注意:

with MyQuery do

begin

Session.StartTransaction;

try

... {Modify data}

ApplyUpdates; {try to write the updates to the database}

Session.Commit; {on success, commit the changes}

except

RestoreUpdates; {restore update result for applied records}

Session.Rollback; {on failure, undo the changes}

raise; {raise the exception to prevent a call to CommitUpdates!}

end;

CommitUpdates; {on success, clear the cache}

end;

对于单数据集的提交:

MyQuery. ApplyUpdates;

MyQuery. CommitUpdates;

8. DataM中提供了一个功能Clone(Source, Dest):一、Dest 是TVirtualTable ,则完整的将源数据集复制;二、Dest 是UniQuery ,则是将Source 的SQL 复制到Dest ,并Open

9. UniQuery.SetReadOnly属性说明

1) 我们经常会用到多表关联,且需要在前台修改数据。举个例子:a 表和b 表,在前台两个表字段都需要修改,则需要将SetReadOnly 设置成false

2) 特别注意:若将一个UniQuery.SetReadOnly 设置成true ,而这个表有一个自增长ID ,那么你在提交数据时会出错,跟踪SQL 会发现,ID 被前台前行传了一个null 值

10.UniQuery. RefreshRecord,可以刷新当前选择的数据

11.我们经常会在UniQuery 的SQL 定义一些参数,在传参时,需要特别注意,例如: QExec.Close;

QExec.SQL.Text:= ‘select * from YHB where sYHBH=:P_YHBH’;

在传参时有两种写法

1) 最稳妥的写法

QExec. ParamByName(‘P_YHBH’).DataType:= ftString;

QExec. ParamByName(‘P_YHBH’).ParamType:= ptInPut;

QExec. ParamByName(‘P_YHBH’).AsString:= ‘张三’;(此处可将AsString 换成Value)

2) 下面这个写法我做了简单测试,也是可以的,但对复杂的SQL 传参是否正确,未知

QExec. ParamByName(‘P_YHBH’).AsString:= ‘张三’;(在不对参数的数据类型和传入传出类型进行指定的情况下,绝对不能使用Value)

UniDAC 的过程中一定要注意,在DataM 中提供了一个函数PrepareParam ,请注意看一下。 在ADO

12.Sybase 的一个特性

update a set a.fSJ=b.fSJ

from table1 a join table2 b on a.sYPBSM=b.sYPBSM

上述SQL 语句在Sybase 下执行不能通过,请改写成如下SQL(在MS 和ASE 中都能执行通过)

update table1 set fSJ=b.fSJ

from table1 a join table2 b on a.sYPBSM=b.sYPBSM

UniDAC 官方网址:

一、连接数据库Connecting to Database

1、 通用连接属性

● Provider

第一个就应该设置的属性,指定要连接的数据库类型,根据指定的数据库连接类型不同其它的设置也会发生相应的变化;

● Username and Password

登录数据的有效用户名和密码;

Server

通常将此设成要连接数据库所在的计算机名或IP 地址,如果将此属性设置为空,对于MySQL, InterBase连接数据库方式, UniDAC 将试图连接本地(Localhost)。

Oracle:

客户端模式下,指定的Server 名称一定要出现在tnsnames.ora 中,且有效,设置效果如下:

with UniConnection1 do

begin

ProviderName := 'Oracle';

Server := 'ORCL';

Username := 'username';

Password := 'password';

end;

直连模式(Direct mode)下:在此模式下,运行软件的计算机可以不安装Oracle 客户端而连接Oracle 数据库,但要做以下设置:

1) 设置直连模式

2) 设置Server

指定Server 格式:Host:Port:SID.

注:客户端模式和直连模式的设置不能混淆,否则无法执行。两种格式严格区分。

效果如下:

with UniConnection1 do

begin

ProviderName := 'Oracle';

Server := '192.168.1.113:1521:ORCL';

Username := ' Username ';

Password := ' Password 3';

end;

SQL Server:

指定要连接的数据库所在的网络IP ,且有效,如果采用的不是默认端口(1433),Server应该这样设置:HostName,PortNumber .

● Database

这个属性只对SQL Server, MySQL, PostgreSQL, InterBase, and SQLite 连接方式有效, ●

指定TCP/IP协议访问的有效端口

MySQL – 默认端口 3306

PostgreSQL -默认端口5432

二、UniDAC (版本:2.7)连接数据库必要文件或局限需求

1、Oracle 连接

Oracle 在采用直连模式将受到以下限制:

特别要注意的是(包括:应用TUniLoader ) :

1) 、应用直连模式,本地执行程序的客户机必须要安装TCP/IP协议

2) 、注意防火墙

3) 、数据库的triggers 、check constraints 、clustered tables 、loading of remote objects 、user-defined types将得不到支持

4) 、available, like OBJECT, ARRAY, REF, XML, BINARY_DOUBLE, BINARY_FLOAT这些类型将变为不可用

5) 、TUniLoader 的应用版本应高于Oracle client 8.17

以下是英文原文:

triggers are not supported ●

check constraints are not supported ●

referential integrity constraints are not supported ●

clustered tables are not supported ●

loading of remote objects is not supported ●

user-defined types are not supported ●

LOBs must be specified after all scalar columns ●

LONGs must be specified last ● You cannot use TUniLoader in a threaded OCI environment with Oracle client 8.17 or

lower.

● Connect using the TCP/IP network protocol only.

● Some types are not available, like OBJECT, ARRAY, REF, XML, BINARY_DOUBLE,

BINARY_FLOAT.

● Certain problems may occur when using firewalls.

● NLS conversion on the client side is not supported.

● Transparent Application Failover is not supported.

● Statement caching is not available.

● OS authentication and changing expired passwords features are not available.

● The DES authentication is used.

● Oracle Advanced Security is not supported.

● We do not guarantee stability of multithreaded applications. It is highly recommended to

use the separate TUniConnection component for each thread when using UniDAC from different threads.

2、 SQL Server连接

1) 提供连接支持

服务端: SQL Server 2005 (including Compact and Express editions), SQL Server 2000, SQL Server 7, and MSDE.

客户端: SQL OLE DB and SQL Native Client.

2) 环境需求

MDAC (Microsoft Data Access Components)版本不低于2.5

3、 My SQL连接

My SQL提供的连接也包括直连和客户端连接方式,默认采用的是直连方式,如果要更改连接方式,在应用程序分发时要带上libmysqld.dll

二、Delphi 与各数据库数据类型比较

Delphi 数据类型与各数据库数据类型对比如下表,如有具体说明见表中脚注:

Delphi Type Oracle Types SQL Server

Types MySQL Types InterBase Types PostgreS QL Types SQLite Types

ftSmallin t NUMBER(p, 0) [2] (p < 5) SMALLINT TINYINT(M) (M > 1) SMALLINT SMALLIN T SMALLIN T TINYINT SMALLIN T

ftWord - TINYINT TINYINT(M) - - -

UNSIGNED (M > 1) SMALLINT UNSIGNED YEAR

ftInteger NUMBER(p,

0) [2] (4 < p < 10)

INT

MEDIUMIN T

MEDIUMIN T UNSIGNED INT

INTEGER INTEGER

INTEGER

INT ftLargein t NUMBER(p, 0) [2]

(9 < p <

19)

BIGINT

BIT INT

UNSIGNED

BIGINT BIGINT UNSIGNED

BIGINT BIGINT BIGINT

ftFloat

NUMBER(p, s) [2]

BINARY

FLOAT(FLO

AT)

BINARY DOUBLE

DECIMAL(p,

s) [3]

FLOAT

REAL

DECIMAL(p, s)[3] FLOAT DOUBLE NUMBER(p, s)[3] FLOAT DOUBLE PRECISI ON DECIMAL

[3]

REAL DOUBLE PRECISI

ON

DECIMAL

(p, s)[3] FLOAT DOUBLE PRECISI ON

ftBCD

NUMBER(p, s) [2] (p < 15) and (s < 5) DECIMAL(p,

s) [3]

(p < 15) and (s < 5)

DECIMAL(p, s)[3] (p < 15) and (s < 5) DECIMAL

(p, s)[3] (p < 15) and (s <

5)

DECIMAL [3] DECIMAL [

3]

ftFMTBcd NUMBER(p, s) [2] (14 < p < 39) and> (4 < s < 39) DECIMAL(p, s) (14 < p < 39) and (4 < s < 39) DECIMAL(p, s)[3] (14 < p < 39) and (4 < s < 39) DECIMAL

(p, s)[3] (14 < p < 19) and (4 < s < 19) DECIMAL [3] DECIMAL [

3]

ftCurrenc y -

MONEY

SMALLMONEY

- - MONEY MONEY

ftBoolean - BIT

TINYINT [4]

BOOL [4] BOOLEAN [4

]

BOOLEAN BOOLEAN BOOLEAN

ftString

VARCHAR2 NVARCHAR2 VARCHAR CHAR NCHAR RAW [5]

INTERVAL DAY TO SECOND INTERVAL DAY TO MONTH ROWID UROWID CHAR

VARCHAR CHAR

VARCHAR ENUM

SET

BINARY [6] VARBINAR Y [6]

CHAR VARCHAR CHAR VARCHAR CHAR

VARCHAR

ftWideStr ing See note [7] NCHAR NVARCHAR

See note [7] [7]

See

note

[7] See note [7]

ftMemo

LONG

Also see

note [8]

TEXT

NTEXT [9]

TINYTEXT TEXT

MEDIUMTE

XT

LONGTEXT

BLOB

TEXT

TEXT

TEXT CLOB

ftWideMem o See

note[10] NTEXT [11]

See

note[10]

See note[10] See note[10] See

note[10

] ftOraClob

CLOB NCLOB -

-

-

-

-

ftBlob LONG RAW IMAGE

TINYBLOB

BLOB MEDIUMBL OB LONGBLOB Spatial Data Types BLOB

BINARY BYTEA BLOB

ftOraBlob BLOB -

- - LARGE

OBJECT -

ftBytes

-

BINARY TIMESTAMP BINARY

-

- - ftVarByte RAW

VARBINARY

VARBINAR CHAR

-

BINARY

s Y

VARCHAR (CHARSET = OCTETS) VARBINA RY

ftDate

-

-

DATE

DATE

DATE

DATE

ftDateTim

e DATE

DATE

DATETIME

TIMESTA MP TIMESTA MP TIMESTA

MP

DATETIM

E ftTime

-

-

TIME

TIME

TIME

TIME

ftTimeSta mp TIMESTAMP

TIMESTAMP

WITH

TIMEZONE -

- - - -

ftCursor REF CURSOR - - - REFCURS

OR -

ftGuid

-

UNIQUEIDENTI

FIER

-

- - - ftVariant - SQL_VARIANT - -

-

-

NOT

SUPPORTED

BFILE

OBJECT

XML

CURSOR XML TABLE

- - - -

[1] – 如果FieldsAsString 选项被设置 True ,则除BLOB 和TEXT 数据类型外,全部做为ftString 来处理

[2] – Oracle NUMBER数据类型与Delphi 数据类型对应方式:

if scale equals zero, provider checks values of the specific options to choose the correct Delphi type in the following order:

1.1 field precision is less or equal Precision Smallint (default is 4) - uses ftSmallint; 1.2 field precision is less or equal Precision Integer (default is 9) - uses ftInteger; 1.3 field precision is less or equal Precision LargeInt (default is 18) - uses ftLargeint;

if scale is greater than zero, the appropriate Delphi type is chosen using the following sequence of rules:.

2.1 field precision is less or equal PrecisionFloat (default is 0) - uses ftFloat;

2.2 EnableBCD is True and field precision, scale is less or equal PrecisionBCD (default is 14,4) - uses ftBCD;

2.3 EnableFMTBCD is True and field precision, scale is less or equal PrecisionFMTBCD (default is 38,38) - uses ftFMTBCD;

2.4 uses ftFloat.

[3] - The appropriate Delphi type is chosen using the following sequence of rules:

EnableBCD is True and field precision, scale is less or equal 14,4 - uses ftBCD;

EnableFMTBCD is True - uses ftFMTBCD;

uses ftFloat.

[4] - If the EnableBoolean option is True

[5] - If the RawAsString option is True

[6] - If the BinaryAsString is True

[7] - If the UseUnicode option is True, all server types mapped to ftString will be mapped to ftWideString.

[8] - If the LongStrings option is False, and the field length is greater than 255, all server types mapped to ftString will be mapped to ftMemo.

[9] - For all Delphi versions prior to BDS 2006.

[10] - If the UseUnicode option is True, in BDS 2006 and later versions all server types mapped to ftMemo will be mapped to ftWideMemo.

[11] - For BDS 2006 and higher IDE versions.

三、UniDAC 更新数据

1、数据自动更新

TUniTable 、TUniQuery 和TUniStoredProc 是用来检索和编辑数据的UniDAC 控件,

四、主从关系表

五、存储过程

1、TUniConnection, TUniSQL, TUniQuery, TUniStoredProc均可以执行存储过程。 TUniConnection :

是一种最简单的执行存储过程的控件,但他有很多限制。TUniConnection 不能具有SQL 、存储过程名和参数,不支持输出参数也不支持存储执行的预准备。当然,如果只是运行一个既没有返回也没有输出参数设置,那TUniConnection 是一个不错的选择。

TUniSQL :

TUniSQL 是一个被分离出的小控件,执行SQL 语句但不返回结果集。它没有数据存储,但要消耗一些内存,但比TUniQuery 和TUniStoredProc 的执行速度快。

TUniQuery :

TUniQuery 除具有TUniSQL 的执行功能外,还能返回结果集。

TUniStoredProc :

TUniStoredProc 是专门用来执行存储过程的一个控件,可以返回结果集、输出参数、执行准备以及通过CreateProcCall 方法初始化等。

2、 参数类型

UniDAC 支持四种参数类型:input, output, input/output, result

六、事务处理

TUniConnection 通过StartTransaction, Commit, Rollback等方法来控制本地事务,判断一个事务是否开启用InTransaction 。

七、控件详解

1、TUniConnection

建立和控件数据连接的控件,能访问的数据库包括:Oracle, SQL Server, MySQL, InterBase, Firebird, 和PostgreSQL.

虽然UniDAC 对不同的数据库提供了统一的访问接口,但是对个别数据库还是要进行一些特殊的设置,这些设置是一个字符串列表,你可以按以下代码进行设置: UniConnection.SpecificOptions.Values['CharLength'] := '1';

1、

Oracle

多线程下使用使用 UniDAC+MSSQL

ADO 线程不安全,UniDAC 在使用MSSQL 也是如此。其实这是微软COM 问题,不怪Devart 公司。

一般解决方法是在线程开始启用 CoInitialize(nil),线程结束调用 CoUninitialize 。如果你使用多种数据库连接,比如三层中经常切换到MSSQL 和Oracle ,我们只需在判断 TUniConnection 的连接前事件 OnBeforeConnect 写下如下代码:

procedure TServDBFunc.ServConnBeforeConnect(Sender: TObject);

begin

if (ServConn <> nil) and SameText(ServConn.ProviderName,'SQL Server');then CoInitialize(nil);

end;

在TUniConnection 的关闭连接后事件 OnAfterDisconnect 写下如下代码:

procedure TServDBFunc.ServConnAfterDisconnect(Sender: TObject);

begin

if (ServConn <> nil) and SameText(ServConn.ProviderName,'SQL Server');then CoUninitialize;

end;

需要注意的是,必须先判断连接控件 (ServConn <> nil) 是否为空,否则,你会陷入指针释放的问题。

unit Unit1;

interface

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids, DBGrids, DB, DBAccess, Uni, MemDS, UniProvider, InterBaseUniProvider;

type

TForm1 = class(TForm)

UniConnTest: TUniConnection;//用于数据库的连接

InterBaseUniProTest: TInterBaseUniProvider;//ib/FB的数据提供

UniQryTest: TUniQuery;

UniDataSrTest: TUniDataSource;

DBGrid1: TDBGrid;

Button1: TButton;

Button2: TButton;

procedure Button1Click(Sender: TObject);

procedure Button2Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

begin

with UniConnTest do

begin

ProviderName := 'interbase';//这里确定为interbase 但是可以支持firebird

Password := 'masterkey';//数据库密码

Username := 'sysdba';//数据库密码

Server := '';

Database := 'TD_HOUSE.FDB';//数据库文件的位置,这里在当前目录 SpecificOptions.Clear;

SpecificOptions.Add('InterBase.ClientLClientLClientLClientLibraryibraryibraryibrary=fbembed.dll');

//设置设置设置设置embeddll 驱动位置

SpecificOptions.Add('InterBase.CharLength=0')

;//设置设置设置设置为0让,

unidacunidacunidacunidac 自动读取fb 设置设置设置设置 SpecificOptions.Add('SQLDialet=3');

//设置设置设置设置为3

SpecificOptions.Add('USEUnicode=true');//迟滞unicode 有人说有问题 我没有发现 try

Connect;

ShowMessage('OK');

except

ShowMessage('eer');

end;

end;

end;

procedure TForm1.Button2Click(Sender: TObject);

begin

UniQryTest.Close;

UniQryTest.SQL.Text := 'select * from TB_SYS_LOG'; //

UniQryTest.FetchingAll;

UniQryTest.DisableControls;

UniQryTest.Open;

UniQryTest.EnableControls;

end;

end.

有网友问我常用的控件及功能。我先大概整理一下,以后会在文章里面碰到时再仔细介绍。 Devexpress VCL 这个基本上覆盖了系统界面及数据库展示的方方面面,是做桌面系统必备的一套控件,目前的版本是2011.2.3, 支持win32 及win64。

AutoUpgrader 这个是自动更新的一个小控件,适合桌面程序自动更新,但是自从2007 年后,就没有更新了,我对其进行了修改,使其可以安装在delphi XE2 上, 同时支持win64。

Devart 公司出品的UniDAC,ODAC,SDAC,IBDAC, 这几个是目前delphi 数据库存取最好的控件,UniDAC 几乎支持所有的数据库存取,而后面几个则是针对每种 提供专用的访问和控制功能,尤其是ODAC ,可以直接使用TCP/IP 连接oracle ,免去安装Oracle 客户端的麻烦,非常适合各种场合应用(在xe2 里面,已经可以直接支持用 Iphone 访问oracle 了)。

Advanced Data Export 和 Advanced Data Import 这是EMS 公司出品的数据导入、导出控件,几乎可以导入、导出常用的各种数据格式,是数据库转换和备份的必备控件。

NativeXml 是生成和解析XML 文件及格式一个非可视控件(使用时,直接引用单元), 是一个轻量级的xml 解析器,支持windows 和linux, 以前是收费的,

现在是开源了(唉,可惜我当时的银子了)。

Paxcompiler 是目前最快的,最稳定的Pascal 脚本解析器,我前面介绍的delphi web 脚本就是使用它做解释器的,目前还不支持win64, 据作者说今年元月底就会支持win64.

kbmMW 是目前唯一与Remobjects 并驾齐驱的delphi 多层解决方案, 比Remobjects 紧凑、便宜,但是功能绝不输给Remobjects 。我后面后介绍使用kbmMW 实现各种多层应用。

TeeChart Pro 在delphi 的图形显示方面目前唯一的选择,虽然从delphi 3 就随delphi 捆绑发布,但是捆绑的是标准版,很多功能都不全,要展示各种绚丽的统计、分析功能,

还是要用专业版(呵呵,领导们都是喜欢这个的)。最新的TeeChart Pro 已经支持firemonkey 了(兼容性还有点问题),你可以把pc 上的绚丽图形放到Iphone 上了。 从 Delphi 1 开始,delphi 每个版本都会有报表工具,但是每次自带的报表工具都相当不给力,几乎没有人使用,因此出现了几个非常不错的第三方报表工具,例如Reportbuilder,

Fastreport 等,由于今年出的delphi xe2 开始捆绑Fastreport 标准版,同时Reportbuilder 的价格高的离谱,而且fastreport 确实非常不错,建议报表工具还是用Fastreport.

Delphi 目前应该还是windows 平台非常强的开发工具,因此经常会用来写

windows 服务,虽然Delphi 本身支持winservice 的开发,但是功能也就是能开发而已,要开发专业的

winservice , 还是要用Svcom , 这个可以像普通程序一样调试服务程序,同时支持 界面和服务在同一个程序里面,调试、配置、安装都非常方便。

这几年随着web 技术的发展,各种JS 框架越来越多,与delphi 后台结合,基本上都需要使用JSON 格式,delphi XE 开始支持JSON ,但是个人认为语法复杂,理解困难,

幸好有开源的Super Object Toolkit,非常直观和简单,在服务器端运行也非常稳定,我上面的文章也有介绍。

以上就基本上是我常用的控件,当然还有些控件由于比较偏,就不再做介绍了。我个人的原则是只要有现成的控件,我不会再去做类似的,毕竟个人精力和能力有限,而人家专业做控件的,

无论从质量和功能上都有保证,同时只要是正版用户,作者都会很及时的修改bug 的,自己把精力放到实现第三方无法实现的地方就可以了