更新序表的应用

在与数据库打交道时,经常对表中的记录进行各种操作,如增、删、改等等。为了更好地处理数据库更新操作,在esProc中提供了更新序表。更新序表是一种特殊的序表,它会存储每一条记录的初始值以及更新状态,并附有记录删除缓存,记录的更新状态有三种:null(0),modify(1)和new(2)。为了了解更新序表的特点与使用方法,我们使用Adventure和Adventure2这两个表来实验说明:
 AB
1=connect("esProc") 
2=A1.query("select * from Adventure")=A1.query("select * from Adventure2")

Adventure如A2所示:

Adventure2如B2所示:

更新序表的创建主要有四种方式:

3=create@u(AId,Name,Country) 
4=A2.create@u() 
5=A2.dup@u() 
6=A1.query@u("select * from Adventure") 

A3中为直接构建更新序表的结构,A4为由序表的数据结构创建,这两种情况下创建的更新序表是没有记录的:

A5为由序表复制为更新序表,A6为直接由查询语句生成更新序表,这两种情况下创建的报表是包含记录的:

这些记录的更新状态通常为null,也可以用@n选项使得记录的更新状态变为new。

下面,我们以A6中的更新序表为例,了解一下更新序表的基本操作。

用U.status(i),可以查看第i条记录的更新状态:

7=A6.len().(A6.status(#)) 

A7中返回A6中的更新序表每一条记录的更新状态:

在修改更新序表中的记录时,可以直接赋值,也可以使用函数r.modify()或者T.modify():

8>A6(2).Country="USA">A6(2).modify(102:AId)
9>A6.modify(8,"USA":Country)>A6.modify(8:2,AId+100:AId)
10=A6.len().(A6.status#()) 

A8、B8、A9、B9这些单元格修改了A6中的更新序表,修改后,A6如下:

此时,A10中查询到A6中更新序表的更新状态如下:

可以看到,第2、8、9这三条记录被修改了,更新状态变为了1。

在更新序表中,可以用U.m@o(i)来查询第i条记录的原记录,需要注意的是,i是当前记录所在的位置,如果更新序表中进行了插入或者删除操作,这个位置也会随之变化。查询原记录的用法如下:

11=A6.m@o(8) 

查询到第8条记录修改前的原记录如下:

在序表中删除记录使用T.delete()函数,删除单条或者多条都是可以的:

12>A6.delete(2)>A6.delete([3,4,5])
13=A6.len().(A6.status#()) 

需要注意的是,删除记录时指定的序号,是序表中当前记录的位置。由于A11中删除了第4条记录,所以后面的记录都会向前顺移一位,因此B11中删除的第3,4,5条记录其实最初的序号是3,5,6。删除后,A6中的更新序表如下:

此时,A12中查询到A6中更新序表的更新状态如下:

由于更新状态是与记录相对应的,因此是查不到被删除的记录的更新状态的。

在更新序表中,是可以对已删除的记录进行查询的:

14=A6.len@d()=[A6.len@d(1),A6.len@d(2)]

A14中,查询到更新序表A6中,删除缓存区的记录总数如下:

B14中,查询出更新序表A6中被删除的第1和第2条记录:

可以看出,在删除缓存区中,记录的存储顺序是与删除操作的顺序相同的。

如果想在序表中插入新纪录,可以使用T.insert()函数:

15>A6.insert(0,13:AId,"US":Country,"Yellowstone National Park":Name)>A6.insert(4,4,"Everglades National Park","US")
16>A6.insert(0:2,13+#,"Everglades National Park"+string(#),"US") 
17=A6.len().(A6.status#()) 

在A13中,在序表A6的最后添加新记录,按名称指定了每个字段的值;在B13中,在序表A6的第4个位置插入新记录,由于未指定字段名称,因此需要按顺序为每个字段赋值;在A14中,在序表A6的最后添加多条新记录。代码执行后, A6中更新序表如下:

此时,A15中查询到A6中更新序表的更新状态如下:

可以看到,第4条和最后3条记录都是新插入的记录,其更新状态为2。

我们已经了解了更新序表的基本操作,以及在操作中更新序表中记录的更新状态的相应变化,现在可以使用db.update()函数将更新序表中的数据提交到数据库了:

18=A1.update(A6,Adventure,AId,Name,Country) 
19=A1.query("select * from Adventure")=A6.len().(A6.status#())

在默认情况下,db.update()是默认提交的,提交后,从A19中,可以看到提交后的数据:

通过和A6中的数据对比,我们可以发现:被修改的数据在数据库中完成了修改,被删除的记录也已经被相应删除,只有新增的记录有一些区别,其中Everglades National Park这条记录,在A6中被插入在第4条,但是由于在数据库中,记录往往按照入库顺序存储,通常是无法将记录新增到指定位置的,因此这条记录出现在新增记录的最前面。

更新序表更新到数据库后,更新状态也会被清除,从B19中可以看到:

使用db.update()时,可以添加@k选项,此时数据不会自动提交到数据库,同时更新序表的更新状态也不会清除。我们把上面的更新语句做一下修改:

18>A1.update@k(A6,Adventure,AId,Name,Country)>A1.commit()
19=A1.query("select * from Adventure")=A6.len().(A6.status#())

提交到数据库的数据是相同的,而从B19中的结果如下:

可以看到,A6中的更新状态没有清除。此时如果想要清除A6的状态,可以使用A6.reset@s()来实现,如果使用了@s选项,reset()函数不会清除更新序表中的所有记录,而只会清除A6中,所有记录的更新状态。

为了更好地理解更新序表的处理方式,我们尝试着把A6中的数据,更新到Adventure2表中:

20=A1.update@a(A6,Adventure,AId,Name,Country)=A1.query("select * from Adventure2")

在B20中,查询到更新后的结果:

为了对比,我们再来看一看Adventure2中的初始数据,可以从B2中查看:

经过对比可以发现,只有更新序表中,更新状态发生了编号的记录才会更新到数据库中,更新状态为null的记录,不会在更新时起到任何作用,这可以有效地提高更新序表的存储效率。更新序表中被删除的记录,和它们主键相同的记录都被删除了;更新序表中修改过的数据,只有原数据库中存在相同主键的记录,才会被修改,而修改后的记录,所有字段全部会和更新序表中的值相同;更新序表中新增的记录,它们同样会添加在数据库的最后,但是,如果原数据库中已存在同主键的记录,新增记录是无法正确添加的,如AId为13的记录,由于Virginia Beach存在,Yellowstone National Park这条新纪录就无法正确添加。还有一点值得注意,在使用更新序表更新数据库时,即使使用了@a选项,也不会在更新前清除原数据库。

最后,作为比照,再来看一下,普通序表的更新是如何进行的:

21=A1.update(B2,Adventure,AId,Name,Country)=A1.query("select * from Adventure2")
22=A1.update@a(B2,Adventure,AId,Name,Country)=A1.query("select * from Adventure2")

在A21中,将序表B2更新到Adventure2中,B21中结果为:

可以看到,普通序表更新时,每一条记录都会参与更新。如果数据库中不存在相应主键的记录,就会进行插入记录操作;如果有同主键记录,则会进行修改。

A22中,用序表更新时,添加了@a选项,B22中结果如下:

可以看到,在更新前数据库被清空,最终数据库中的结果和序表B2是相同的。

如果用普通序表更新数据库,所有记录都会尝试更新。如果数据量很大,而且其中只有少量记录有变化时,用普通序表更新数据库效率就会十分低下,此时就应该使用更新序表了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值