非常难的问题,如何指定ADOTABLE只按主键更新.(50分)

  • 主题发起人 主题发起人 xksyhjb
  • 开始时间 开始时间
X

xksyhjb

Unregistered / Unconfirmed
GUEST, unregistred user!
非常难的问题,如何指定ADOTABLE只按主键更新.
本人在用ADO数据集更新数据时,如果数据提取后其它用户更改了该条记录内容.则更新失败.
特向高手讨教.
我又不想把数据集设置为服务器端.因为太慢,又不支持排序.
如何解决.
 
我有解决办法,这是我的邮件,请和我联系
mymail@sohu.com
 
不难,用ADO的动态属性就可以完成 。
 
呵呵,xeen已经给出解决方法.
我再提醒一下,你在网上可以下载李维的<Delphi 5.X ADO_MTS_COM+高级程序设计篇>第四章
的第39页开始到45页有详细的论述.

因为是PDF格式,我只能拷贝一些文字,如下:
如果你使用过B D E / I D A P I来存取数据,那么就会知道在B D E - I D A P I的数据集
组件中有一个属性叫U p d a t e M o d e。U p d a t e M o d e能够控制数据集组件如何把数据更
新回数据库中,例如,如果程序员设定数据集组件的U p d a t e M o d e为u p W h e r e A l l,
那么当数据集组件要更新数据回数据库中时,便会在它产生的S Q L命令的w h e r e子
句中使用数据表所有字段的旧字段值来找到原始的数据,再更新找到的这笔数据。
而如果程序员设定数据集组件的U p d a t e M o d e为u p W h e r e K e y O n l y,那么数据集组件
只会在它产生的S Q L命令的w h e r e子句中使用数据表中键值字段的旧字段值来搜寻
原始的数据,再更新找到的这笔数据。
第4章深入了解ADO 2 2 5
同样,在A D O中也有一个属性来控制A D O引擎如何更新数据回数据库中,这
个属性就是U p d a t e C r i t e r i a。A D O默认的更新数据的行为是以数据表的键值字段以
及被修改的字段来做为搜寻旧数据的条件。例如,在一个名为E m p l o y e e的数据表
中,有A、B、C、D和E 5个字段,其中A是键值字段。如果我们在客户端的A D O
应用程序中修改了一笔数据的C和E字段值,那么当我们要把修改的数据更新回
E m p l o y e e数据表中时, A D O引擎会使用类似如下的S Q L命令来执行这个数据的修
改:
Update ... Where A=A 的旧字段值and C=C的旧字段值and E=E的旧字段值
从上面的S Q L命令中可以看到, A D O默认的修改数据规则是以数据表的键值
字段和所有被修改的字段做为搜寻原始数据的标准。
这个修改数据的行为便是由A D O的R e c o r d s e t对象的U p d a t e C r i t e r i a动态属性控
制的,因此我们可以通过设定U p d a t e C r i t e r i a动态属性值来改变A D O如何搜寻要被
修改的数据。在D e l p h i的A D O I n t程序单元中定义了U p d a t e C r i t e r i a可以设定的属性
值。下面的表格列出了这些数值以及它们的意义。
常数数值说明
A d C r i t e r i a K e y 0 只在S Q L命令的W h e r e子句中使用键值字段值来寻找
原来的记录
A d C r i t e r i a A l l C o l s 1 在S Q L命令的W h e r e子句中使用所有的字段值来寻找
原来的记录
A d C r i t e r i a U p C o l s 2 在S Q L命令的W h e r e子句中使用键值字段以及所有被
修改的字段值来寻找原来的记录,这是A D O使用的默
认设定
a d C r i t e r i a Ti m e S t a m p 3 在S Q L命令的W h e r e子句中使用键值字段以及数据表
中字段类型为Ti m e S t a m p的字段来寻找原来的记录
从上面的表格中可以看到, A D O提供了多种选项让程序员能够选择要使用的
更新规则。不同的U p d a t e C r i t e r i a设定值会影响修改的数据是否能够成功更新回数
据表中。尤其是在一个多人使用的应用系统中,相同的一笔数据可能会同时被数
个用户同时修改,那么U p d a t e C r i t e r i a的设定值就会极大地影响用户能否成功地把
数据更新回数据表中。
那么我们要如何控制A D O如何更新数据回数据库之中呢?这个问题的答案就
等于如何控制A D O的动态属性U p d a t e C r i t e r i a。要控制A D O的动态属性事实上非常
2 2 6 Delphi 5.x ADO/MTS/COM+高级程序设计篇
下载
简单,就是从A D O的动态属性集合对象中取出要改变的属性对象,再把新的动态
属性值指定给取出的属性对象的Va l u e属性值。让我们撰写一个改变U p d a t e C r i t e r i a
动态属性的范例来说明如何使用D e l p h i来动态地改变A D O的默认执行行为。
1) 在D e l p h i的集成开发环境中建立一个新的项目,然后在主窗体中加入如图
4 - 2 5所示的V C L组件。
图4-25 范例应用程序的主窗体
在这个主窗体中使用了TA D O C o n n e c t i o n和TA D O D a t a S e t连接到MS SQL
Server 7的E m p l o y e e数据表,激活TA D O D a t a S e t的字段编辑器,加入E m p l o y e e数据
表的所有字段并且把这些字段拖曳到主窗体中以便让D e l p h i自动产生数据感知组件
字段。最后放入一个T R a d i o G r o u p组件并在其中加入所有可供选择的U p d a t e C r i t e r i a
选项,以及一个执行改变U p d a t e C r i t e r i a选项的按钮“改变Update Criteria”。
2) 在主窗体的“改变Update Criteria”按钮的O n C l i c k事件处理程序中撰写如
下的程序代码:
c o n s t
adCriteriaKey = $00000000;
adCriteriaAllCols = $00000001;
adCriteriaUpdCols = $00000002;
adCriteriaTimeStamp = $00000003;
p r o c e d u r e TForm1.Button1Click(Sender: TObject);
v a r
vConn : OleVariant;
第4章深入了解ADO 2 2 7
下载
rs_ : _RecordSet;
pty : Property_;
pties : Properties;
f u n c t i o n getCriteria : Property_;
v a r
iCount : Integer;
b e g i n
rs_ := ADODataSet1.Recordset;
pties := rs_.Properties;
f o r iCount := 0 t o pties.Count - 1 d o // Iterate
b e g i n
pty := pties.Item[iCount];
i f (pty.Name = 'Update Criteria') t h e n
b e g i n
Result := pty;
b r e a k ;
e n d ;
e n d ; // for
/ /或是使用Result := pties. Get_Item('Update Criteria');
e n d ;
b e g i n
ADODataSet1.Active := True;
pty := getCriteria;
pty.Value := GetSelectedCriteria;
e n d ;
f u n c t i o n TForm1.GetSelectedCriteria : Integer;
b e g i n
c a s e rgUC.ItemIndex o f / /
0 :
b e g i n
Result := adCriteriaKey;
e n d ;
1 :
b e g i n
Result := adCriteriaAllCols;
e n d ;
2 :
b e g i n
Result := adCriteriaUpdCols;
e n d ;
2 2 8 Delphi 5.x ADO/MTS/COM+高级程序设计篇
下载
3 :
b e g i n
Result := adCriteriaTimeStamp;
e n d ;
e n d ; // case
e n d ;
在上面的程序代码中,当用户在T R a d i o G r o u p 组件中点选了要使用的
U p d a t e C r i t e r i a并且点选了按钮之后,就先启动TA D O D a t a S e t组件,因为动态属性
必须是在R e c o r d s e t对象启动的状态下才能取得。接着O n C l i c k调用g e t C r i t e r i a以取
得U p d a t e C r i t e r i a这个动态属性对象。
g e t C r i t e r i a函数首先从TA D O D a t a S e t中取得它封装的R e c o r d s e t对象,再存取
R e c o r d s e t对象的动态属性集合对象P r o p e r t i e s。最后进入一个循环,从这个集合对象中
搜寻U p d a t e C r i t e r i a这个动态属性对象。在这里我使用了循环来搜寻U p d a t e C r i t e r i a动态
属性,这是为了说明用。如果是在撰写真正的应用程序,那么我们可以调用P r o p e r t i e s
对象的G e t _ I t e m方法,并且传入要搜寻的动态属性名称,这样做会比较有效率。
最后,当O n C l i c k正确地取得了U p d a t e C r i t e r i a动态属性对象之后,再调用
G e t S e l e c t e d C r i t e r i a函数以取得用户在T R a d i o G r o u p组件中选择的U p d a t e C r i t e r i a选
项,并且直接指定给U p d a t e C r i t e r i a动态属性对象的Va l u e属性。
现在请编译这个范例应用程序,并且执行它看看它是否真的可以改变A D O如
何搜寻要被更新的数据。图4 - 2 6是范例应用程序执行的画面,请注意此时我并没有
在T R a d i o G r o u p组件中选择任何U p d a t e C r i t e r i a选项。
图4-26 范例应用程序执行的画面
第4章深入了解ADO 2 2 9
下载
然后修改上图中l n a m e字段的数据并且点选T D B N a v i g a t o r组件中的P o s t按钮以
便把数据更新回数据表中。图4 - 2 7是使用MS SQL Profiler观察的结果。
图4-27 SQL Profiler显示ADO用来更新数据的SQL命令
从图中可以看到, A D O在搜寻字段的数据要被更新的W h e r e子句中使用了
e m p _ i d和l n a m e这两个字段。其中e m p _ i d是E m p l o y e e数据表的键值字段,而l n a m e
则是修改数据的字段。因此我们可以知道在不选择任何U p d a t e C r i t e r i a选项的情形
下,A D O是使用A d C r i t e r i a U p C o l s这个选项来处理修改的数据。
现在让我们继续在范例应用程序中的T R a d i o G r o u p组件中选择使用A d C r i t e r i a
A l l C o l s选项,并且再次修改l n a m e字段的数据,再把这笔数据更新回数据表中。如
图4 - 2 8所示。
图4-28 在范例应用程序中使用不同的更新数据原则要求ADO更新数据
而图4 - 2 9是改变了U p d a t e C r i t e r i a选项之后MS SQL Profiler观察到的结果。
从上图中我们可以看到,现在A D O果然在W h e r e子句中使用了所有的字段来
搜寻要被更新的原始数据,可见改变U p d a t e C r i t e r i a选项的确可以改变A D O的执行
行为。

 
多人接受答案了。
 
后退
顶部