登录 用户中心() [退出] 后台管理 注册
   
您的位置: 首页 >> 程序员学前班[不再更新,只读] >> 主题: ado 会删除从表中的内容     [回主站]     [分站链接]
标题
ado 会删除从表中的内容
clq
浏览(0) + 2008-11-01 12:25:49 发表 编辑

关键字:

ado 会删除从表中的内容

解决方法如下:

gxx (2003-2-25 23:47)
ADO支持join来的记录集的更新,并且支持的非常完美。
其主要思路是在单表更新后,回查当前记录。
{
//================================================================
//利用ADO特性实现多表更新的例子

//注意最后面的那个带参数的字段,必须是主键主段

strCommandText = 'select t1.ID,t1.a1,t1.a2,t1.a3,t2.b1,t2.t2,t2.b3 from t1,t2 where t1.id=t2.fid';
strResync = 'select t1.ID,t1.a1,t1.a2,t1.a3,t2.b1,t2.t2,t2.b3 from t1,t2 where t1.id=t2.fid and id=?';

ADODataSet1.CommandText:=strCommandText;

必需同时指定下面的两个动态属性,才能实现多表更新
其实是只更'Unique Table'指定的那个表,
另一个表的数据重新查询回来,但回查当前记录以及与记录集合并的过程是自动的
而使用ADODataSet1.ReQuery将重查所有记录,造成当前记录指针的变化,网络转输数据量也偏大

ADODataSet1.Properties['Unique Table'].Value := 't1';
ADODataSet1.Properties['Resync Command'].Value := strResync; //在AfterOpen中设置

//同步数据集,在AfterPost事件中调用,这样只要在存盘后,
//可以返回查当前记录中数据库存动生成的值,如默认值,自增加字段,也可返回Join来的字段
//其实就是使用strResync语句查回当前记录
ADODataSet1.Recordset.Resync(adAffectCurrent, adResyncAllValues);
}

请高手指正!


--------------------------------------------------
问题如下:
--------------------------------------------------

标题:Ado+Dcom三层应用中主从表删除的问题 (50分)
kaithink (2003-4-3 17:0) 1735943
这是我的测试模型,假设一个员工有一个以上GF。
设有四个表,[]表示主键,()表示外键
部门表:kDept=[DeptNo],DeptName
员工表:kEmp=[EmpNo],EmpName,(DeptNo),Addr,tel
学校表: kSchool=[schoolNo],schoolName
女友表: kGF=[EmpNo,GFNo],GFName,LikeColor,HomeTel,HomeAddr,(SchoolNo)
----------------------------------
中间层远程数据模块内:
主表QEmpGFMst.Sql={
Select A.EmpNo,A.EmpName,A.DeptNo,A.Addr,A.tel
,B.DeptName
From kEmp A
Left Join kDept B on A.DeptNo=B.DeptNo'
}
从表QEmpGFDtl.SQL={
Select A.EmpNo, A.GFNo,A.GFName,A.LikeColor,A.HomeTel,A.HomeAddr,A.SchoolNo
,B.SchoolName
From kGF A
Left Join kSchool B on A.SchoolNo=B.SchoolNo
Where A.EmpNo=:EmpNo
}
------------------------------------
数据提供者
DspEmpGF.ResolveToDataSet=True;
DspEmpGF.Options=poCascadeDeletes;
DspEmpGf.UpdateMode=upWhereKeyOnly
------------------------------------
数据集QEmpGFMst与Dtl中主键字段的
ProviderFlags.pfInUpdte=True,
ProviderFlags.pfInWhere=True,
ProviderFlags.pfInWhere=True;
非主键真实字段
ProviderFlags.pfInUpdte=True;
从其他表关连来的字段如DeptName,SchoolName,ProviderFlags均为False;
客户端ClientDataSet设置与中间层数据集一致,并且主表的数据集字段CdsMstQEmpGFDtl.ProviderFlags.pfInUpdte=True;
--------------------------------------------------
问题:
删除一个员工的一个女友时,学校表中该女友的所上学校记录也被删除;
删除一个员工时,该员工的部门也被删除,并且从表记录没有被删除。
kaithink (2003-4-4 20:14)
请各位高手关注一下这个问题吧,我在CSDN上发的贴子,复者几乎没有。
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
ADO数据集组件能够处理多表更新操作,也就是针对JOIN语句中的所有表进行更新
(包括insert,edit,delete)。

数据提供组件的级联删除属性是针对后台数据库设置了主从表关联并且该RDBMS支持级联删除的,
否则该属性设与不设都不会在删除主表时自动删除关联的从表记录;

如果你不需要多表更新,也就是说你像我一样只想更新FROM 后边的表,并不想更新 JOIN 后面的表的话,
请将数据提供组件的ResolveToDataSet设为False.

至于删除主表记录时随之删除从表关联记录,我想触发器是一种好的选择。

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

我已经找到方法解决了
有两种方法
一、设置数据提供者的ResolveToDataSet为False,也就是不使用ADO组件来进行更新操作。
二、在合适的事件过程中进行如下处理:
ADODataSet1.properties['unique table'].value:='tblEmp';
即告诉ADO要更新的表名;
因为在数据集打开后才能进行原生对象的属性值设置,在C/S下可写在onAfterOpen事件中;
在ADO+DCOM下写在数据提供者的onBeforeUpdataRecord事件中是测试过可行的,但最合适在
哪一个事件过程中还不太清楚。


\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\


呵呵,stonegern:
你找一下ADO的参考文档看一下,我第一次用啊,初学者一个!
只是最近在测试ADO的主从表,问题很多啊。

***************************
* 测试最新结果:--<触发器删除从表记录的模式>   *
***************************

在前面问题解决的情况下,又发现新问题。
为kEmp表设了个触发器{
CREATE TRIGGER kEmpMst_Del ON [dbo].[kEmp]
FOR DELETE
AS

Delete kGF
From kGF, Deleted
Where kGF.EmpNo = Deleted.EmpNo
}

在frmMainTest只放ADODATASETkEmp+DS1+DBGrid1,
AdoDataSetkEmp.commandtext为{
Select A.EmpNo,A.EmpName,A.DeptNo,A.Addr,A.tel
From kEmp A }

一、出错时机:

//删除按钮
begin
AdoDataSetkEmp.delete;//无缓存更新时,则马上出错!!有缓存更新时则在缓存更新时出错
end;
//缓存更新
begin
AdoConnection1.BeginTrans ;
try
AdoDataSetkEmp.UpdateBatch; //前面执行了删除时,出错
AdoConnection1.CommitTrans;
except
AdoConnection1.RollbackTrans;
raise;
end;
end;

二、出错信息:

在后台查看,当AdoDataSetkEmp当前记录没有对应的kGF表记录时,错误信息为:
-->""无法为更新行集定位:一些值可能已在最后读取后改变。""

在后台查看,当AdoDataSetkEmp当前记录有多于一条对应的kGF表记录时,错误信息为:
-->""键列信息不足或不正确。更新影响到过多的行。""

三、成功情况:

在后台查看,当AdoDataSetkEmp当前记录只有一条对应的kGF表记录时,删除就正确了。


\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

当我对第二张单据删除两条从表记录,然后移到第三张单据,添加两条从表记录,更新后,
删除的那两条还在!寒。。。

当我对第二张单据添加修改或删除从表记录,然后移到第三张单据,添加修改或删除从表记录,更新后,
对第二张单据从表的添加修改或删除没有了。

这是在缓存更新的状况下的测试!


kaithink (2003-4-7 18:14)
这是否是ADO的BUG?
谁知道啊?
bbs-wqt (2003-4-7 18:24)
关注!
无忧鱼 (2003-4-8 12:17)
当然会出现这样的问题,没什么奇怪 的,如果你用数据库更新那么只有设
ADODataSet1.properties['unique table'].value
我认为更好的方法是自己写方法保存了,虽然麻烦点,不过益处多多
kaithink (2003-4-8 13:40)
不管怎么设,只要主表设了触发器去删除从表记录
那么在前台设用主表的DELETE时就有问题。
kaithink (2003-4-9 12:45)
ttttttt
kaithink (2003-4-21 8:36)
结论:
一.

ado(or+dcom)主从表, 主表在后台设了触发器去删除从表 ,在前台对主表记录调用delete方法

在后台查看,当主表当前记录没有对应的从表记录时,错误信息为:
-->""无法为更新行集定位:一些值可能已在最后读取后改变。""

在后台查看,当主表当前记录有多于一条对应的从表记录时,错误信息为:
-->""键列信息不足或不正确。更新影响到过多的行。""

但是,要注意,DELETE和触发器都已执行,该删除的都删除了,问题只在于如果
在前台显式打开事务处理这个过程的话,那么就因为那个后来的错误总是回滚事务

所以,当后台主表有触发器删除从表时,不宜在前台对主表数据集调用DELETE!

二.
ado主从表,C/S,缓存更新

当对第二张单据删除两条从表记录,然后移到第三张单据,添加两条从表记录,更新后,
第二张单据删除的那两条还在!

当我对第二张单据添加修改或删除从表记录,然后移到第三张单据,添加修改或删除从表记录,更新后,
对第二张单据从表的添加修改或删除没有了。

三.

防止ADO进行多表更新,有两种方法任选其一即可
1、设置数据提供者的ResolveToDataSet为False,也就是不使用ADO组件来进行更新操作。
2、在ado数据集合适的事件过程中进行如下处理:
ADODataSet1.properties['unique table'].value:='tblEmp';
即告诉ADO要更新的表名;
因为在数据集打开后才能进行原生对象的属性值设置,在C/S下可写在onAfterOpen事件中;
在ADO+DCOM下写在数据提供者的onBeforeUpdataRecord事件中是测试过可行的,但最合适在
哪一个事件过程中还不太清楚。


kaithink (2003-4-21 8:37)
close
得分富翁:bbs-wqt-25,无忧鱼-25,

clq
2008-11-1 12:57:38 发表 编辑

不过据说对添加时无效,从表还是会添加记录。

总数:1 页次:1/1 首页 尾页  
总数:1 页次:1/1 首页 尾页  


所在合集/目录



发表评论:
文本/html模式切换 插入图片 文本/html模式切换


附件:



NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.

Copyright © 2005-2020 clq, All Rights Reserved
版权所有
桂ICP备15002303号-1