大家看看这段代码问题处在那里?批处理不能保存到数据库(50分)

  • 主题发起人 主题发起人 chendy095
  • 开始时间 开始时间
C

chendy095

Unregistered / Unconfirmed
GUEST, unregistred user!
procedure TMyCoCl.UpdateData(var vData: OleVariant;
out ErrorMessage: OleVariant);
var filename:string;
begin
ErrorMessage:='';
//error 致空
//判断有无另外事务
if ADOConnection1.InTransaction then
begin
ErrorMessage:='保存错误';
exit;
end;
try
ADOConnection1.begin
Trans;
//开始事务
ADOQ_update.Recordset:=IUnKnown(vData) as _Recordset;
/////////////////////////////////////////
ADOQ_update.UpdateBatch(arAll);
//保存
///////////此句不能有效执行,不报错,但是数据没有被写入数据库,为什么?
ADOConnection1.CommitTrans;
//提交事务
except
on E: Exceptiondo
begin
ADOConnection1.RollbackTrans;
//事务回滚
if (pos('Violation of PRIMARY KEY',E.Message )<>0) or
(pos('违反了 PRIMARY KEY 约束',E.Message)<>0) then
ErrorMessage:='主键重复!'
else
if pos('changed by another user',E.Message)<>0 then
ErrorMessage:='另外用户已修改了记录,保存错误!'
else
if pos('Unique key',E.Message)<>0 then
ErrorMessage:='违反唯一性约束!'
else
ErrorMessage:=E.Message+'保存错误!';
end;
end;
ADOQ_update.close;
end;
批处理不能保存到数据库,希望大家不吝赐教啊,是不是Recordset数据集只能只读打开,不能增删改?如能该怎么写?
 
主要是
ADOConnection1.begin
Trans;
//开始事务
ADOQ_update.Recordset:=IUnKnown(vData) as _Recordset;
/////////////////////////////////////////
ADOQ_update.UpdateBatch(arAll);
//保存
///////////此句不能有效执行,不报错,但是数据没有被写入数据库,为什么?
ADOConnection1.CommitTrans;
//提交事务
这段代码出了问题,vData 是我修改过的数据,大家指点一下
 
难道没有人知道吗?
 
请问你的vData是一个dataset??查了一下help,在你执行命令前最好判断一下recordset的 RecordSetState property,应该是sitting idle but open才能够执行吧。
 
vData 是一个 dataset ,ADOQ_update.Recordset:=IUnKnown(vData) as _Recordset;这一句没有问题,我测试时将其输出到dbgrid都是正常的,唯独没有保存到数据库中,郁闷中...,vData这个东西是我从客户端返回来的修改后的数据集,我希望将其更新到数据库中
,谢谢 fukadalwx 同志的提醒,我试试再看
 
一行一行写吧,_Recordset是一个无链接的数据集
 
那可要郁闷死,一行行写速度也太慢了,就是为了实现高速保存我才这样做,几十万条的记录啊,看来这个结构要改了,我还有个想法,将它保存到文本,然后再读入ado,再批量保存,这样速度不会慢的
 
还没有解决嘛??刚刚又看到这个,不知道你这个dataset的属性有没有被正确的设置:
1 The component‘s CursorType property must be ctKeySet (the default property value) or ctStatic.
2 The LockType property must be ltBatchOptimistic.
3 The command must be a SELECT query.
 
_Recordset本身的属性问题
ADOQ_update.UpdateBatch(arAll)
我追踪到这里,数据库没有变化,ado打开的那个属性是只读的
不能将其改为更新数据源的属性,否则会抱错,这个问题已经找到替代方案了
谢谢大家关心
还有什么新的想法请大家交流一下
to fukadalwx :
我先将ADOQ_update.Recordset 以savetofile 保存到文件中,再从我从文件中读入(loadtofile)后,不用做任何修改就可以保存了,为什么?
 
奇怪,你为什么不能保存啊,我下午有空测试了一下,完全没有问题啊,你的那些属性有没有设置啊??下面是我的测试代码:
procedure TForm1.Button1Click(Sender: TObject);
var
ErrorMessage:string;
begin
ADODataSet1.Filter:='id = ''9'' or id = ''6''';
ADODataSet1.Filtered:=true;
ADODataSet1.FilterGroup := fgPendingRecords;
if ADOConnection1.InTransaction then
begin
ErrorMessage:='保存错误';
exit;
end;

try
//ADOConnection1.begin
Trans;
//开始事务
//ADODataSet1.UpdateBatch(arAll);
--修改所有的行
ADODataSet1.UpdateBatch(arFiltered);
--修改过滤的行
//ADOConnection1.CommitTrans;
//提交事务
except
on E: Exceptiondo
begin
//ADOConnection1.RollbackTrans;
//事务回滚
if (pos('Violation of PRIMARY KEY',E.Message )<>0) or
(pos('违反了 PRIMARY KEY 约束',E.Message)<>0) then
ErrorMessage:='主键重复!'
else
if pos('changed by another user',E.Message)<>0 then
ErrorMessage:='另外用户已修改了记录,保存错误!'
else
if pos('Unique key',E.Message)<>0 then
ErrorMessage:='违反唯一性约束!'
else
ErrorMessage:=E.Message+'保存错误!';
end;
end;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
with ADODataSet1do
begin
close;
filtered:=false;
//CursorLocation := clUseServer;
CursorType := ctKeyset;
LockType := ltBatchOptimistic;
CommandType := cmdText;
CommandText := 'SELECT * FROM lwx_ado_test';
Open;
end;
end;
如果你要对所有行的修改都生效就不用设置那个filter了。
 
to fukadalwx:
你有没有这样试过: 在应用服务器端 用ADOQuery打开一个表,将数据ADOQ_update.Recordset 通过dcom整体传送到客户端,这时关闭这个服务器端连接,客户端进行修改后,又将整个ADOQ_update_cilent.Recordset 以OleVariant 的参数形式(vData)传递给 应用服务器端(就是我贴出来的代码),这种情况下的批处理(_Recordset), 请注意这一句
ADOQ_update.Recordset:=IUnKnown(vData) as _Recordset;我觉得应该是这一句问题。
我对_Recordset不是很理解,希望你不要厌烦啊,分数可以在加的。就是想将Recordset这数据传输方式搞清楚一点。
谢谢你的热心帮助,你的这个方法肯定会成功的,在两层的这种连接下试不会有问题的
另外我还想问一下 我用DCOM传递过来的数据vData ,执行这句ADOQ_update.Recordset:=IUnKnown(vData) as _Recordset;
没有问题,而我改用SOCKET传递过来的却会报错,是不是这两个封包有不同?
望赐告
我也是在搞一种能够快速将10万以上数据记录进行传输的方法,以前搞的那种最普通的行不通了,数据量大的时候服务器就死掉了
能否告诉我你的邮箱,我将我的测试代码发给你,你看看是否能调得通
 
对不起,其实我对delphi的认识也不深(可能都没有你的深),不过我很愿意跟你一起学习研究。对了,你用的三层是midas嘛??这么大的数据量处理我想如果客户端多了肯定会当掉的,不知道你们公司有没有使用过中间件的,比如bea的tuxedo??呵呵,我们公司用的现在都是这种,然后在前台在开发数据控件来连接这些中间件服务的,这样处理比较快也方便。如果可以你可以发到我的邮箱:luwx_stb@21cn.net,如果我看不懂的话我再找人帮你看。
 
对了,再问个问题,你在这句: ADOQ_update.Recordset:=IUnKnown(vData) as _Recordset;能不能提取到ADOQ_update里面的数据呢??如果可以我想就不是传输的问题了。
 
不客气了,很感谢你对我的支持啊,没有什么对不起的阿,呵呵,你说得那个中间件我们没有用过,我们这里以前是那种伪三层的连接方式
所以我在找另外的方法来实现这个功能,你们公司用到的中间件我找找资料,研究研究
我将我测试用的代码发给你,d6+sql2000
我们共同探讨这个话题,这几天我要出差上不了网了,不能及时回复你了,再次谢谢你。
 
奇怪,测试了一下的确不能够更新数据库,在服务端用另外一个clientdataset接收返回的数据,的确有看到更新的数据,就是没有更新数据库。按照李维写的,更新数据库有两种办法,如果把datasetprovider的属性resolvetodataset设为false(default)则update的sql语句由dataprovider自动生成,如果设为true则由它连接的dataset来产生,并且可以在beforeupdate事件里面对要更新的字段进行过滤,然后在onUpdatedata事件里面处理客户端传来的更新数据。现在用第一种办法老是行不通,我再试试第二种行不行。
 
用第一种办法是可行的,注意在客户端要用Applyupdate(-1),就可以更新数据库。但是用Applyupdate(0)就死活不行,我查了一下,0应该是必须所有的更新成功才提交,-1是忽略更新的错误,而且在applyupdate(-1)后调用refresh也不行,老是报“必须先调用applyupdate把数据写会数据库&quot;,可见缓存还保有未更新的数据,搞得我现在刷新数据只能先close后再open。这两个问题不知道有没有谁能够解释一下其中的道理?
但是这种方法只适合单表的更新,对于多表的更新,就只能用第二种办法,现在我还没有调通。
 
帮顶!
http://www.source520.com
站长开发推广同盟 站长朋友的终极驿站
同时拥有海量源码电子经典书籍下载
http://www.source520.com/search/search.asp
&quot;编程.站长&quot;论坛搜索引擎-----为中国站长注入动力!
 
多人接受答案了。
 
后退
顶部