为何不能删除关系表中主表的记录?(188分)

  • 主题发起人 主题发起人 于小澜
  • 开始时间 开始时间

于小澜

Unregistered / Unconfirmed
GUEST, unregistred user!
数据库: SQL Server
连接控件: ADOtable或ADOquery (连接的都是主表)
操作: 删除记录,用 ADOtable1.delete或SQL语句(delete...from...)
错误提示: raised exception class EOleException with
message'the specitied row could not be located
for updating: Some values may have been changed
since it was last read'
1、库中的关系表是一对多的,并且在主表上有删除触发器,用来删除和从表
关联的记录,触发器的代码肯定没有问题.我在SQL Server中试过删除主
表的记录,从表的关联记录也能随之删掉,很正常。
2、我在SQL Explorer中删除主表记录一切正常。(因为我的一个朋友告诉
我Delphi不能使用的SQL Server的触发器,一用就出错,删了触发器就
好了)
我自己感觉问题可能是在ADO控件,我试过用Table和query都没有问题,请
各位帮忙,谢谢!
 
CursorLocation改一改看看
CursorType改一改看看
 
如果,删除主表数据时不用报错可直接删除从表数据,
用主健级联删除
 
我用ADOTable , ADOQuery 删除都正常,应该是触发器写的有问题,把触发器贴出来看看!
 
CusorLocation 和CUrsorType的作用?
 
to yubo:
sql server可以用主键级联删除吗?请教怎么设置?我原来都是写触发器。
 
这个问题我碰到过,用SQL删除决没有问题,可能别的地方有毛病,首先设置CusorLocation:=clUseClient;CursorType:=ctStatic
或ctKeySet,如果LockType是ltOptimistic则这样删除
try
ADOQuery.Edit;
ADOQuery.Delete;
except
ADOQuery.Cancel;
end;
很怪吧,没见过删除之前还要Edit出了异常还要Cancel;但ADO数据集就是这样。跟触发器
无关,我估计是Delphi的ADO控件的问题,VB和VI都没有问题,与此相关的奇怪之处就更多
了,这里不一一列出。
如果LockType是ltBatchOptimistic那么,删除时没有问题,问题在保存有点玄妙:
ADOConnection1;ADOQuery1(主表),ADOQuery2(明细表)
if not ADOConnection1.InTransaction then
ADOConnection1.BeginTrans;//如果不在任何一个事务则开始一个事务。
try
ADOQuery1.UpdateBatch;//提交主表
except
ADOConnection1.RollbackTrans;//提交失败则回滚
exit;
end;
try
ADOConnection1.Errors.Clear;
ADOQuery2.UpdateBatch;//提交明细表,
except
ADOQuery1.CancelUpdates;//提交失败则取消对主表的提交。
Exit;
end;
ADOConnection1.CommitTrans;//若主表,明细表提交成功则,结束事务
又是怪事,非要主细表分开提交不可,若非如此,肯定出错,
我对ADO控件已经忍无可忍了。
 
>>主键级联删除:

mastertable.beforedelete
begin
with detailtable do
while not eof do
delete;
end


 
to jqw:
不是吧,还不如触发器?
 
看来各位运气不好,我怎么重来没有碰到过问题?估计还是触发器写的不对。
 
to daiqingbo:
我觉得差不多
 
D5可以用tigger的,级联删除
procedure DelRecord(key:String);
begin
aqmaster.sql.clear;
aqdetail.sql.clear;
aqmaster.sql.add('delete from master where pk = ' + key);
aqdetail.sql.add('delete from detail where fk = ' + key);
aqdetail.exescql;
aqmaster.execsql;
end.
如果不考虑效率,以前我写的这个可以实现主细删除:
a:='';
a:=dbedit1.Text;
begin
if application.MessageBox('如果该商品大类型下有商品小类型的数据,将同时删除,继续吗?','警告',MB_YesNo+MB_ICONWARNING)<>ID_Yes
then exit
else //如果选择删除该大类,先在大表里定位,得到要删除的大类型编号,然后在小类型表里,选择出所有的小类型,然后删除小,再删除大。。
begin
x:=DataModuleWork.MGdindata.Locate('stypedesc',a,[]);
if x=true then
begin
b:=datamodulework.MGdindataSTYPEONENO.Value;
with datamodulework.DGdindata do //Dgindata:TADODataset
begin
close;
commandtext:='select * from gdtypetow where stypeone=:c';//c是参数
// unprepare;
parameters.ParamByName('c').value:=b;
// prepare;
open;
end;
if (datamodulework.DGdindata.State<>dsedit) then //www怎么说不能在dsedit下才能delete?
datamodulework.DGdindata.Edit;
datamodulework.DGdindata.First;
while not datamodulework.dGdindata.Eof do
begin
datamodulework.DGdindata.Delete;
datamodulework.dgdindata.Next;
end;

// datamodulework.DGdindata.Post;
if (datamodulework.MGdindata.State<>dsedit) then
datamodulework.MGdindata.Edit;
datamodulework.MGdindata.Delete;
end; //x=true后的begin所属于的end;
end; //else begin
end;//end of


 
千中元﹐我的信收到了么?
 
接受答案了.
 
后退
顶部