如何在三层C/S结构中同时更新多个表?(200分)

Y

yan

Unregistered / Unconfirmed
GUEST, unregistred user!
台湾李维用TUpdateSQLProvider组件使ApllyUpdates方法在三层C/S结构
中能同时更新多个表,但delphi4最终并没有加入这个组件.请问同时更新多
个表的最好方法?我不想用永久字段,因为表结构会经常变动(临时生成);用
主从明细表好象不灵活,如何是好?
 
ClientDataSet1.ApplyUpdates(-1);
 
对不起:没看到问题的后办部分!
 
能在说清楚点吗?
 
在三层C/S结构中同时更新多个表方法有二:
方法1:使用TUpdateObject更新,比较适合字段比较固定的系统.
方法2:增强TUpdateSQLProvider,分析SQL语句动态生成Update SQL语句.
方法二我做过,效果一般.
 
>>"但delphi4最终并没有加入这个组件"
是什么意思?难道delphi4并没有加入
我们就不能用?
Inprise的网站上也有这个控件可以下载,
不知道是不是说明这个东东也是被Inprise认可的。
 
感谢几位富翁的答复!我的意思是:如果要开发三层C/S系统,必须要解决同时更新
多个表的问题,李维的方法可行,但同时也是万不得已的方法.宋兴烈说做过,应该
清楚这一方法的不足.TUpdateSQLProvider是在delphi3.01之前推出的,如果它
是这个问题的好的解决方案,我想Borland会在3.01,3.02中就加入它,在4.0中也
会有.但在4.0中我们看到了TDatasetProvider而没有TUpdateSQLProvider,这应
该表明了Inprise的态度.从4.0的帮助中看到,Inprise推荐了两种解决方案:
1.用永久字段联系细目表.如果表结构固定,这是一个完美的方法.可惜......
2.在服务器端建立主细表,在客户端用增强的DBGrid支持,但细目表的窗口是由系
统自动popup的,我们不好控制它.况且我还想用其它的数据敏感组件.
我想Inprise不会对TUpdateSQLProvider的思路无动于衷,很可能会有类似
的或更好的解决方案已经存在,但我不知道.
我可是盯上几位首富了,望不吝赐教,分不够我还有!
 
这是Borland提供的TUpdateSQLProvider的说明,
截取自该控件的注释部分,不知道是否是你所希望的。
如果需要,控件可以寄给你,不过也许跟李维的控件没什么区别。

{*******************************************************}
{ }
{ Sample TProvider }
{ }
{ Copyright (c) 1997 Borland International }
{ }
{*******************************************************}
unit USQLProv;

This component demonstrates how to create a custom TProvider for greater
control of the update process. It combines the TUpdateSQL component with
TProvider to perform updates. The addition of an OnUpdateRecord event
allows business rules to be enforced on a record by record basis before
and after the updates are performed.
To use:
o Compile and install the DCLUSP30.DPK package.
o Create a remote data module with a TTable, TQuery or TStoredProc.
o Drop the TUpdateSQLProvider component and set the DataSet property.
o Export the UpdateSQLProvider using the option on the component menu.
From this point you would typically add an OnUpdateRecord event handler
with code to implement whatever sort of business logic you require. You can
use the DataSet parameter of the event to access the old and new field
values. The Query parameter is initialized with the pending update SQL
statement and the appropriate Param values set.
If you want to change the values which will be written to the database you
can assign values directly to Query.Params. For example:
Query.Params.ParamByName('LAST_MODIFIED').AsDateTime := Now;
If you want to prevent an update from being performed, simply raise an
EDatabaseError exception inside the event and it will be returned to
the client. For example:
if DataSet.FieldByName('Salary').NewValue > 500000 then
DatabaseError('Salaray is out of range');
If you need to check the data after the updates are applied, you may want
to perform the updates yourself inside the OnUpdateRecord event. If you
do
this, set the Applied parameter to True.
The SQL statements used to apply the updates may be specified at design time
or automatically generated at runtime. To create the statements at design
time, right-click on the component and choose "UpdateSQL editor..." from the
component menu. If you generate update statements at design time, the updates
will work only if the fields listed in the WHERE clause are not NULL;
SQL
requires that the WHERE clause be formatted as "Field is NULL" when dealing
with NULL values. If you leave the InsertSQL, DeleteSQL or ModifySQL
properties blank, then
the update statements will be automatically generated
at runtime.
This code provides a good starting point for any type of custom TProvider
implementation. In particular, it demonstrates how to extract the update
information from the Delta datapacket, how to handle errors, and how to
build a result datapacket.
SQL Generation Notes:
o You can disable the automatic SQL generation by including sgDisabled
in the SQLGenOptions property. In this case you must use the
OnUpdateRecord event to assign the update SQL yourself or perform the
actual update.
o In some cases the generated SQL will put quotes around the field and
table names. You can disable this by excluding sgUseQuotes from the
SQLGenOptions property.
o By default, the update statements include only fields which were modified
by the client. You can force all fields to be included in the update
statement by including sgAllFields in the SQLGenOptions. This may
improve performance in cases where there are a large number of updates
to be performed. It may also be necessary if you have business rules
which assign values to fields which were not modified by the client.
o If a value is given for the TableName property it will be used when
the update SQL is generated. This would is useful when the associated
dataset is a TStoredProc component or if you have a TQuery executing
a stored procedure.
o The generated SQL is based on the data in the delta datapacket. If the
associated dataset is a TQuery with a join, the generated SQL will not
be valid.

 
你可以使用Com,自己编写接口,来完成一个事务处理。
 
在中间层提供三个函数,StartTransaction,commit和Rollback.
自己可以随意在客户端组织事务.
客户端一定注意回滚.
All is ok.
代码太简单了.不用附了.
 
dwwang,请把你的TUpdateSQLProvider控件寄来好吗?我已经走投无路了!
本打算用RTTI之类的方法去控制那个由DBGRID弹出的窗口,但最终还是失
败了.因为我用的是Oracle 8.0.4 for NT,恰好Delphi 4不支持Oracle
带索引的嵌套表,白忙.
另外请宋兴烈谈谈使用TUpdateSQLProvider的经验.
李唯已出了Delphi 4实战篇,其中对DCOM做了深入讲解,有谁见过?
我个人认为这个问题应该有更好地解决方法,但现在只能如此了.
请寄到:geolab@hebtu.edu.cn
非常感谢!
 
接受答案了.
 
顶部