我们来研究一下数据库的错误信息:
A | B | |
1 | =connect("esProc") | |
2 | =A1.query("select * from movies where title like'G%'") | |
3 | =A1,query("select * from movies2") | |
4 | >A1.update(A2,movies2,Mid,Title,Studio,Gross) | |
5 | =A1.query("select * from movies2") | |
6 | >A1.close() |
表movies中存储了一些较为详细的电影信息,A2中从movies中取出片名首字母为“G”的电影资料。表movies2中的数据要求Mid>40,原本没有记录。
A2中的运算结果如下:
A3中的运算结果如下:
A4准备将A2中电影的简要信息存储入表movies2中。但是,由于movies2对数据的限制,在存入数据时,并不是所有的操作都能执行成功。
在A5中,查询到movies2中的数据如下:
经过比较可以发现,大部分数据成功存入了,而“Grown Ups”这部电影由于数据不符合movies2的要求,而未存入。
在默认情况下,我们是不知道A4中的操作是成功还是失败,或者是部分成功的,这就使结果变得不可预知了,这对于数据库管理可不是一个好现象。为了知道数据库在执行操作时是否成功,我们需要在产生连接时,使用@e选项,以使错误信息可以被获知。
我们仍然使用movies和movies2两个表来做实验:
A | B | |
1 | =connect@e("esProc") | |
2 | =A1.query("select * from movies where title like'G%'") | |
3 | >A1.execute("delete * from movies2") | |
4 | >A1.execute("insert into movies2 values(?,?,?,?)",A2(1).Mid, A2(1).Title,A2(1).Studio,A2(1).Gross) | =A1.err0r() |
5 | =A1.query("select * from movies2") |
在A1中,生成数据库连接时使用了@e选项,这样在出错时将可以由代码自行处理。A2中的查询结果和前面是一致的:
在A3中,清除了movies2中的数据;A4在movies2中插入A2中的第一条记录。由于“Grown Ups”这部电影不符合movies2中的要求,因此可以在B4中看到错误代码:
而moves2中也未存入数据,A5中结果为:
6 | >A1.execute("insert into movies2 values(?,?,?,?)",A2(2.)MId,A2(2).Title, A2(2).Studio,A2(2).Gross) | =A1.error() |
7 | =A1.query("select * from movies2") |
由于A6中的语句执行正常,因此在B6中的错误代码为0:
而从A7中也可以看到,记录存入正常:
再看批量执行语句的情况:
8 | >A1.uodate@a(A2,movies,MId,Title,Studio,Gross) | =A1.error() |
9 | =A1.query("select * from movies2") |
A8试图将A2中的所有记录存入movies2,使用@a选项,可以在执行更新前将movies2中的数据先清除。尽管只有第一条记录不符合movies2中的要求,其它记录均可以正常更新,在B8的结果中,仍然会返回错误代码:
而在A9中,可以看到,只有符合要求的记录被插入了movies2:
如果执行的语句全能正确执行呢?A10中仅取出A2中Mid>60的记录进行更新,仍然使用@a选项在更新前清空目标表movies2:
10 | >A1.uodate@a(A2.select(MId>60),movies,MId,Title,Studio,Gross) | =A1.error() |
11 | =A1.query("select * from movies2") |
B10中的错误代码为0:
从A11中可以看到,A10中的操作都得到了正确执行:
可见,无论是单条执行命令还是批量执行命令,一旦产生错误,就可以从错误代码中获得信息。
在处理数据库事务时,有时候需要根据情况,来决定是将改动写入数据库,还是取消操作,这个时候,就需要使用db.commit()和db.rollback()来进行控制。
在默认情况下,在esProc中执行语句都是自动提交的,此时是无法自行控制的。如果想用db.commit()和db.rollback()来进行控制,需要在执行语句时使用@k选项。这样,就可以根据错误信息,来决定数据是否有效了。如下面的例子,在批量执行更新时,如果产生错误,则所有数据全部无效,这样就可以避免数据库中出现不可预知的结果:
A | B | |
1 | =connect("esProc") | |
2 | =A1.query("select * from movies where title like'G%'") | |
3 | >A1.execute("delete * from movies") | |
4 | >A1.update@k(A2,movies2,MId,Title,Studio,Gross) | |
5 | if A1.error()==0 | >A1.commit() |
6 | else | >A1.rollback() |
7 | =A1.query("select * from movies2") | |
8 | >A1.update@k(A2.select(MId>60),movies2,MId,Title,Studio,Gross) | |
9 | if A1.error()==0 | >A1.commit() |
10 | else | >A1.rollback() |
11 | =A1.query("select * from movies2") | |
12 | >A1.close() |
A3中,将movies2中的数据清空,由于在执行db.execute()时未使用@k选项,因此会自动进行提交。
A4中,执行批量更新时,会产生错误,这可以从A5的运算结果中看到:
因此会执行B6中的回滚操作,数据不会写入数据库。A7中的查询结果如下:
使用@k选项进行批量更新时,如果未产生错误,如A8中执行的语句,也可以从错误信息中查看,A9中值为:
此时执行B9中的提交操作,数据写入数据库。A11中的查询结果如下: