用游标执行计算

除了从游标中读取数据,在集算器中还可以直接使用一些函数,用游标完成常用的数据计算。如从游标中根据条件选出数据:

 

A

B

1

=file("Order_Books.txt")

=A1.cursor@t()

2

=B1.select(SalesID==1)

=A2.fetch()

3

=A2.fetch()

=B1.fetch()

 

B1生成外存文件游标,A2根据B1的游标中选出1号销售员的销售数据。查看A2中的数据如下:

 

可以发现,A2中的结果,和B1中是相同的。和序表或排列中的select函数不同,在游标中使用select函数时,返回的结果是游标本身,计算A2时其实并未真正从游标中获取数据,而是在游标上附加运算。在B2中执行fetch时,才会根据条件在B1游标中检索数据,结果如下:

 

B2中使用fetch时,未指定返回条数,也未设定读取条件,此时会返回游标A2中的所有数据,即1号销售员的所有销售数据。A2中游标的数据全部读取后,会自动关闭。同时,由于A2中的游标和B1中的游标是相同的,在检索数据时,实际上是在B1的游标中遍历并执行附加的运算,因此A2游标中的数据读取完成时,B1游标中的数据同样完成了读取,会被关闭。所以,此时在A3B3中,无法再从A2或者B1的游标中读取数据。

如果文件中的数据是有序的,可以用f.iselect(A,x,Fi,…;s) f.iselect(a:b, x,Fi,…;s) 函数来选择数据生成游标,以提高效率。如:

 

A

B

1

=file("Order_Books.txt").iselect@t(["S020000012", "S020000022"],ID; ID,PID,Date,Amount)

=A1.fetch()

2

=file("Order_Books.txt").iselect@ti(date(2013,2,1): date(2013,2,28),Date; ID,PID,Date,Amount)

=A2.fetch@x(100)

 

由于文件中包含字段名,因此添加@t选项,类似的,如果使用的是集文件,可以添加@b选项。A1中使用f.iselect(A,x,Fi,…;s)中,按照订单ID查找销售记录,在默认情况下,使用iselect函数检索数据时,要求对应的数据是唯一的。A2中使用f.iselect(a:b, x,Fi,…;s) 函数来查找一段日期期间内的销售记录,这里添加了@i选项,表明Date不是唯一的,检索时会返回符合要求的全部数据。执行后,B1B2中的结果分别如下:

 

另外,还可以根据游标来生成新记录,或者添加计算字段,如:

 

A

B

1

=file("employee.txt")

=A1.cursor@t(EID, NAME,SURNAME, GENDER, STATE,BIRTHDAY)

2

=B1.new(EID, NAME+" "+SURNAME: FullName, GENDER,STATE,BIRTHDAY)

=B1.derive(age(BIRTHDAY):Age)

3

=A2.fetch(100)

=B2.fetch(100)

4

>A2.close()

=B2.fetch()

5

>B2.close()

 

 

B1中使用外存文件employee.txt生成文件游标,生成时选出部分字段。在A2中根据B1游标中的NAMESURNAME字段,拼成员工的全名。B2中则在B1游标中计算出每位员工的年龄添加到Age列。与cs.select() 相同,cs.new() cs.derive() 这两个函数同样返回游标,而并不会直接开始返回数据。运行后,A2B2中的游标和B1中是相同的:

 

A3中检索出前100条数据如下:

 

使用cs.new() 函数生成数据,相当于对每一条记录执行new计算。

B3中检索出100条数据如下:

 

使用cs.derive() 函数生成数据,相当于在返回的序表中添加计算列。

可以发现,B3中的数据与A3中的结构是相同的,而且是从第101位员工开始的。这是由于A2B2中只是在游标中添加了计算,实际使用的是同一个游标,而游标中的数据只会从前往后执行单次遍历。因此A3执行后,游标已经查询了100条,B3再执行fetch时,就只会继续读取数据,也就会从第101位员工开始了。

由于游标中的数据并未全部读出,因此使用完毕后应该用close关闭游标。当A4中关闭了A2中的游标时,由于A2B1中的游标是相同的,因此B1中的游标也会同时被关闭。如果试图继续读取数据,结果为空。

 

另外,还可以用cs.run() 来修改游标读取的数据中,某个字段的值,如:

 

A

B

1

=file("employee.txt")

=A1.cursor@t(EID, NAME,SURNAME, GENDER, STATE,BIRTHDAY)

2

=demo.query("select STATEID, NAME, ABBR from STATES")

=B1.run((a=STATE, STATE=A2.select@1(NAME==a).ABBR))

3

=B2.fetch(100)

>B2.close()

 

B2中,将返回数据中的州换为对应的简称。返回的仍然是被添加了计算的游标:

 

A3中读取前100条数据如下:

 

与序表类似,在游标中还可以使用switch转换,将读取出的数据中字段转换为其它序表中对应的记录,如:

 

A

B

1

=file("employee.txt")

=A1.cursor@t(EID, NAME,SURNAME, GENDER, STATE,BIRTHDAY)

2

=demo.query("select STATEID, NAME, ABBR from STATES").keys(STATEID)

=B1.switch(STATE,A2:NAME)

3

=B2.fetch(100)

>B2.close()

 

B2中,用cs.switch() 对游标中的数据执行转换,B2中的结果仍然是添加了计算的游标:

A3中读取出数据如下:

 

可以看到,返回的结果中,STATE字段转换为了对应的州记录。

在使用cs.switch() 时,也可以一次处理游标中的多个字段,如:

 

A

B

1

=file("employee.txt")

=A1.cursor@t(EID, NAME,SURNAME, GENDER, STATE,BIRTHDAY)

2

[F,Female,M,Male]

=create(ID,Gender).record(A2).keys(ID)

3

=demo.query("select STATEID, NAME, ABBR from STATES").keys(STATEID)

=B1.switch(GENDER,B2;STATE,A3:NAME)

4

=B3.fetch(100)

>B3.close()

 

B3中,同时转换游标中的多个字段为其它序表中的对应记录,A4中读取前100条记录如下:

主键与引功能中,讲述了普通序表中,switch的使用。在外存计算中使用cs.switch() 时,和序表中的使用是类似的。在switch执行前,同样会为对应的维表字段建立索引表以提高效率。由于使用游标时,往往是需要处理大批数据的,因此这样的处理方式更为必要。