AdoQuery的 UpdateBatch的问题

青云 2005-11-26 07:37:02
举一个非常简单的例子:

比如有一个表:
create table 商品信息
(
商品编号,
商品总数量,
包装数量
)

其中:

"包装数量" 是指: 一个箱子里所装的商品数量;




数据是:
商品编号 商品总数量 包装数量
001 107 10
002 190 20


这个表非常简单;


我们做个程序对这个表维护,非常简单;
只需要设置:
AdoQuery1.LockType:=ltBatchOptimistic;//批量更新数据模式;
AdoQuery1.Sql.text:='select 商品编号,商品总数量,包装数量 from 商品信息';
AdoQuery1.open;
DataSource1.DataSet:=AdoQuery1;
DbGrid1.DataSource:=DataSource1;

如果需要维护数据,我们可以直接在DbGrid1上进行修改实现;



如果写程序,就5句代码实现所有的维护功能;
//1、添加
AdoQuery1.Append;
//2、修改
AdoQuery1.Edit;
//3、删除
AdoQuery1.delete;
//4、保存
AdoQuery1.UpdateBatch;
//5、取消
AdoQuery1.CancelBatch;

多么简单的程序,不需要专门写'insert into...'这样的语句实现维护;
而且也不需要我们人为判断哪些数据被更新过,AdoQuery1.UpdateBatch时会自动通过
AdoQuery1.UpdateStatus 来识别哪些数据被更改过,系统会生成相应的Sql语句作更新;


但是,大家注意没有“商品总数量 包装数量”显示的信息不够直观;

如果我们把:

商品编号 商品总数量 包装数量
001 107 10
002 190 20

换成这样的显示:

商品编号 商品整箱数 商品零数 商品总数量 包装数量
001 10 7 107 10
002 9 10 190 20

我想客户会看的更明白;

同样客户在进行单据维护的时候,也是直接输入:“商品整箱数” 和“商品零数 ”来实现;
但是这两个字段不存在,是通过我们算出来的,真实的数量信息只有“商品总数量”这个字段;



所以我想这样做程序:

//1、设置;
AdoQuery1.Sql.text:=
'select
商品编号,
商品总数量,
trunc(商品总数量/包装数量) as 商品整箱数,
商品总数量-trunc(商品总数量/包装数量) as 商品零数,
商品总数量,
包装数量 from 商品信息';

AdoQuery1.FieldByName('商品整箱数').ReadOnly:=false; //允许维护;
AdoQuery1.FieldByName('商品零数').ReadOnly:=false; //允许维护;
AdoQuery1.FieldByName('商品总数量').ReadOnly:=true; //不让维护;

//更新总数量
procedure Tform1.AdoQuery1BeforePost(DataSet:TdataSet);
begin
AdoQuery1.FieldByName('商品总数量'):= AdoQuery1.FieldByName('商品整箱数').asInteger*
AdoQuery1.FieldByName('包装数量').asInteger+
AdoQuery1.FieldByName('商品零数').asInteger;
end;


//2、维护
AdoQuery1.Append;
AdoQuery1.Edit;
AdoQuery1.Delete;

3、保存
AdoQuery1.UpdateBatch;



这样的做法非常非常简单,但是如果大家真的按照这种做法作,会发现有问题:

比如:
你在DbGrid上填写了一个“商品整箱数”和“商品零数”,当你在DBGrid上定位到其它记录上再回到着这条记录的时候,你会发现该记录中的"商品整箱数"和"商品零数"全部为空,也就说你刚才写的没有效果;

这种现象说明一个非常重要的一个问题:
AdoQuery只对表里原生字段的维护敏感,对于经过函数变换后生成的字段,它是不能识别的。



为了实现能够在"商品整箱数"和"商品零数"这两个字段上维护的功能。我尝试了很多方法;

最简单的方法就是改变Sql语句的写法:

AdoQuery1.Sql.text:=
'select * from
(select
商品编号,
商品总数量,
trunc(商品总数量/包装数量) as 商品整箱数,
商品总数量-trunc(商品总数量/包装数量) as 商品零数,
商品总数量,
包装数量 from 商品信息)';

这样在"商品整箱数"和"商品零数"上维护了,
但是这样产生了一个致命的问题:AdoQuery1.UpdateBatch; 这个非常生猛的保存函数实效了;

我们更新数据只能自己手工写更新语句“insert into ... ,update .. delete ”,这还不是最麻烦的。
最麻烦的是:我们还要判断哪些数据是被添加的,哪些数据是被修改的。哪些数据是被删除的。哪些数据没有发生变化; 而如果能用 AdoQuery1.UpdateBatch;就什么都不用考虑;

我提出了这个问题,希望大家提出建议;

也许有人会说把
create table 商品信息
(
商品编号,
商品总数量,
包装数量
)

修改成:

create table 商品信息
(
商品编号,
商品整箱数,
商品零数,
包装数量
)

但是我这里是提出一个现象,希望大家能够在不改变表结构的情况下,以最简单的方法解决这个问题;
希望能至少实现以下几点:
1、不需要自己手工写"insert into ..."这样的语句实现更新数据;
2、不需要判断哪些表作了什么样的更改,能够通过系统自动识别;
3、数据批量更新,可以任意在DbGrid上作任何维护操作,最后统一提交给数据库;
...全文
547 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
rockswj 2005-11-27
  • 打赏
  • 举报
回复
那两个字段用计算字段来实现
Antiquesoft 2005-11-27
  • 打赏
  • 举报
回复
楼上的说对了!

计算字段!

那几个值是算出来的,根本不需要去保存!
madyak 2005-11-26
  • 打赏
  • 举报
回复
提交时,是很麻烦。只可以解决界面编辑时的问题
青云 2005-11-26
  • 打赏
  • 举报
回复
楼上的朋友,我一般用oracle 数据库,您提供的临时表方法,我不太熟练。
能否再说的具体点,
但是我有两个疑问:
1、临时表的数据是不需要保存的;
2、您通过select * from #MYTEMP 来实现维护数据,那么通过AdoQuery1.UpdateBatch是更改了
##MYTEMP,对于原表“商品信息”它是如何处理呢?

madyak 2005-11-26
  • 打赏
  • 举报
回复
不知道你用的什么数据库,你考虑过用临时表没有?
select
商品编号,
商品总数量,
trunc(商品总数量/包装数量) as 商品整箱数,
商品总数量-trunc(商品总数量/包装数量) as 商品零数,
商品总数量,
包装数量
INTO #MYTEMP
from 商品信息
select * from #MYTEMP
青云 2005-11-26
  • 打赏
  • 举报
回复
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3277199

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧