分享
 
 
 

动态创建ClientDataSet的表定义

王朝delphi·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

前言

很多人都在问,ClientDataSet如何才能在不连接数据库得情况下,用程序创建起来,并打开数据集。

在研究了一下TClientDataSet数据集后,发现如果要让ClientDataSet打开的话(Open),必须满足三个条件中的一个:

PRoviderName属性赋值,即有数据源提供者。

Data属性赋值。即从其它已经打开的数据集中获得表结构和数据。

FileName赋值,即从本地文件获取数据和MetaData。

这三个条件是TClientDataSet的Active属性的帮助中说的。思考一下,第一和第二基本被排除,我如果有了现成的数据集,还要创建干吗?第三个又不是那么容易,你哪知道文件的格式是什么呢?

那到底该怎么做呢?

失败的尝试

突然想起TClientDataSet中支持InternalCalc(内部计算)字段。内部计算字段可以在设计期加进去,或者也可以在运行期动态加入。我们为了方便,就在设计期加入。见下图:

可以通过双击控件(TClientDataSet)进入字段编辑器,然后右键选择“New Field”命令,得到如图所示的界面。填写Name,Type和FieldType。

记住:FieldType一定要是“InternalCalc”。如此反复,你可以选择添加多个字段。

打开!报错:“ProviderName”或Data没有赋值。

这个方法不正确,既然要Data,我尝试着,从其它ClientDataSet的Data属性赋值上。得到结果是:自己新建的字段和数据源的字段都显示。

我又进行了进一步的尝试:那就是让这个有着新建的字段和原有字段的ClientDataSet的Data赋值到另一个新的ClientDataSet上,却发现新建的字段没有进入。

总得来说,这次尝试是失败的,不过有如下总结:

光靠新建内部计算字段是不可行的。

新建的计算字段不可以进入Data属性而被传递给第二个ClientDataSet。

xml

又是XML!ClientDataSet本就是断开连接的数据集控件,应此提供了将数据缓存到磁盘的功能SaveToFile(),其详细声明如下:

procedure SaveToFile(const FileName: string = ''; Format: TDataPacketFormat = dfBinary);

注意到其中的TDataPacketFormat。它是个枚举类型,全部的枚举值如下:

TDataPacketFormat = (dfBinary, dfXML, dfXMLUTF8);

大家可能注意到了,dfBinary和dfXMLUTF8都不是我们需要关心的,关心一下我们的dfXML格式。这是个让人兴奋的消息。有了XML,我们就可以查看ClientDataSet的MetaData的定义,而且更有了修改的可能!

调用一下SaveToFile功能,注意保存格式为dfXML。打开文件,如下显示:

<?xml version="1.0" standalone="yes" ?>

- <DATAPACKET Version="2.0">

- <METADATA>

- <FIELDS>

- <FIELD attrname="NormInfoID" fieldtype="i4">

<PARAM Name="PROVFLAGS" Value="7" Type="i4" Roundtrip="True" />

</FIELD>

<FIELD attrname="Description" fieldtype="string.uni" WIDTH="160" />

<FIELD attrname="NormInfoVal" fieldtype="string.uni" WIDTH="510" />

<FIELD attrname="NewField" fieldtype="i4" />

<FIELD attrname="Boolean" fieldtype="Boolean" />

<FIELD attrname="Date" fieldtype="date" />

<FIELD attrname="Time" fieldtype="time" />

</FIELDS>

<PARAMS DEFAULT_ORDER="1" PRIMARY_KEY="1" />

</METADATA>

<ROWDATA />

</DATAPACKET>

看这个全部的,比较混乱,先看一下结构:

<?xml version="1.0" standalone="yes" ?>

- <DATAPACKET Version="2.0">

+ <METADATA>

<ROWDATA />

</DATAPACKET>

这下比较清楚了:

整个XML定义为一个DataPacket,DataPacket包括两个部分:MetaData和RowData。显然对我们来说,RowData可以忽视,到时候将RowData的节点清空就是。而MetaData呢?

看看全部的XML格式,可以看出:MetaData包括Fields和Params。即字段和数据集参数。

字段

先重点考虑Fields。看一下Field节点的定义,大概可以看出一些:

attrname是指FieldName

fieldtype是指字段类型

width是需要宽度的字段类型的参数

如果需要定义字段的属性,再加上<Param />节点

下面我们来研究一下字段类型,我想这也是最主要的!其它属于高级用法。

MSSQL Type

fieldtype

WIDHT

SUBTYPE

DECIMALS

READONLY

Binary

bin.hex

50

Bit

boolean

Char

string

10

FixedChar

DateTime

dateTime

Decimal

fixed

18

Float

r8

Image

bin.hex

Binary

Int

i4

Money

fixed

19

4

nChar

string.uni

20

nText

bin.hex

Text

Numeric

fixed

18

nVarChar

string.uni

100

SmallDateTime

dateTime

Real

r8

SmallInt

i2

SmallMoney

fixed

10

4

Text

bin.hex

Text

TimeStamp

bin.hex

8

true

tinyInt

i2

UniqueIdentifier

string

38

Guid

VarBinary

bin.hex

50

Binary

VarChar

string

50

见上表,这是我在SQLServer2000中,将所有类型的字段都用上,然后在ClientDataSet中得到的,类型对应关系。注意到有SubType属性,来帮助决定类型。其中没有值的单元格,表示该属性没有用到。宽度值中,除了UniqueIdentifier是38外,其余都是采用系统默认宽度。

分析一下这一张表,可以得到如下一些特点:

后缀uni表示unicode,没有后缀,则表示是AnsiCode

后缀hex表示16进制

i后的数字表示整数所占用的位数,默认为4位

r8表示8位浮点数

字段参数

注意到某些字段的定义下有节点:

<PARAM Name="PROVFLAGS" Value="7" Type="i4" Roundtrip="True" />

先来解释一下“PROVFLAGS”,在Delphi的源码里查找可以发现其实就是对应着TField的属性ProviderFlags,那么7也就是好理解的了。

看TProviderFlag和TProviderFlags的定义

TProviderFlag = (pfInUpdate, pfInWhere, pfInKey, pfHidden);

TProviderFlags = set of TProviderFlag;

既然是集合,那么7很显然就是一个集合的整数表示:按顺序排的话,7其实就是表示结合[pfInUpdate, pfInWhere, pfInKey]。

不过不知道为什么,查看TField的属性,pfInKey不在集合中。

MetaData属性

看看

<PARAMS DEFAULT_ORDER="1" PRIMARY_KEY="1" />

可以看出DEFAULT_ORDER和PRIMARY_KEY的意思,但是后面的值呢?研究之后,发现,它是主键或索引字段的Index。如果同时两个字段都是索引,那么它的格式是:"1 2",中间采用空格隔开。

如何使用XML格式?

好了,格式大概都知道了,现在问题是如何转载到ClientDataSet呢?

文件是可以,但是显然不满足我们当初的需求,在查看一下接口定义,发现除了LoadFromFile还有LoadFromStream。查看一下源码,其实LoadFromFile就是调用了LoadFromStream。

好了,只要我们创建了这样的XML流,就可以动态创建ClientDataSet了!

至于如何创建XML流,不在此讨论了

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有