查看: 5667|回复: 3

[精华] 活用SQLCA

[复制链接]
招聘 : 系统管理员
论坛徽章:
5
ITPUB元老
日期:2005-02-28 12:57:00授权会员
日期:2005-10-30 17:05:33管理团队2006纪念徽章
日期:2006-04-16 22:44:45会员2006贡献徽章
日期:2006-04-17 13:46:342012新春纪念徽章
日期:2012-01-04 11:49:54
跳转到指定楼层
1#
发表于 2001-12-14 09:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
审编:李志韬  

--------------------------------------------------------------------------------

  ----DB2应用程序使用SQL通讯区(SQLCA)将信息返回到程序中,有些信息是有用的,有些不是;有些是有意义的,有些不是。如果能它们区分开来,那么我们可以利用SQLCA信息来提高程序代码的效率,减少DB2调用的开销,从而简化程序逻辑,提高性能。
  SQLCODE
----SQLCA中最常使用的域是SQLCODE,许多程序员知道在每一次调用DB2以后都应该检查SQLCODE,以确定该调用是否成功。大多数程序者会把SQLCODE是否为+0,作为成功调用的标志。同时还会检查SQLCODE是否为+100,作为文件结束的标志(没有记录或没有更多的记录)。对于其他的SQLCODE,不管是正值或负值,程序一般都执行错误处理例程,结束程序或事务。但是,SQLCODE为负值并不一定表示错误非常严重,以至于要结束程序。并且,某些SQLCODE为正值时,可以有非常有趣的方式利用它。
----我们可以对一些负的SQLCODE定制响应代码,以减少CPU启动和运行程序的开销。例如,可以编写程序处理-911(不能获得要求的锁,事务被回滚),程序可以简单的重试,直到成功或重试计数到某一个值。但应该注意的是:出于数据完整性的理由,重试必须从程序恰当的执行点开始。重试点不一定是重新执行失败的语句,尤其是对那些隐式地回滚事务的SQLCODE。
----负的SQLCODE通常代表程序执行中的意外错误,但某些情况下,可以编写特定的SQL语句故意使程序获得负值返回,然后通过测试预期的负值,简化逻辑判断的代码,从而减少DB2页面读取的数目。
----例如,某一个大电话公司有两种类型的发票:一种给只有一条电话线的住宅用户,另一种给有多条电话线的公司用户。在处理每一个客户时,处理客户发票的程序对该客户做一次COUNT(电话账单表非常大)。如果COUNT的结果为一,则程序转入住宅用户发票格式处理,如果COUNT的结果大于一,则转入公司用户发票格式处理。最后,在发票格式化的过程中,每个客户的记录又再次被读入。在这种程序逻辑下,每一个客户的账单信息不必要地读入了两次,包括即些非常大的商业客户,他们有几百条电话线。
----其实可以将程序逻辑修改一下,对每一个客户做的简单的选择(SELECT ...INTO ),然后测试返回的SQLCODE是否为+0(即仅有一条电话线,转入住宅用户发票格式),或者-811(多于一条电话线,单选操作失败,转入公司用户发票格式)。显而易见,这样可以节省大量的时间。而其他的解决办法或者需要改变表结构,并且占用数据库管理员和程序员更多的时间。
----另一个利用SQLCODE来提高性能的例子如下:每一个输入事务有两种操作,如果有匹配记录,则更新它,否则插入一条新记录。效率低下的程序可能会首先做一个选取(SELECT),判断记录是否存在。然后当SQLCODE为+0时,已经有的记录会再次被读入并更新;当SQLCODE为+100时,插入新的记录。更有效率的方法应该首先尝试最常发生的情况。如果更新比插入更频繁,则首先尝试更新,并检查SQLCODE是否为+0(成功更新了该记录),如果SQLCODE为+100(未发现匹配的记录),再插入该记录。相反,如果插入比更新频繁,则首先可以执行插入,并检查SQLCODE是否为+0(成功插入),或者-803(发现重复记录),这时再更新该记录。任何一种方法都可以消除不必要的重复选择开销。
SQL警告

  ----大多数程序都忽略SQL警告,但这样做并不合适,因为警告对于测潜在问题和简化程序逻辑很有帮助,所以虽然警告不是严重信息,但不应该被忽略。  
  ----在SQLCA中有两个警告信息的指示:一个是SQLCODE大于+100;另一个是SQLWARN0域为W。当任何一个出现时,就表明在上一次调用时DB2发生了一些值得注意的事情,虽然DB2返回了数据,但是可能与预期的有出入。当SQLWARN0是W时,DB2也在其他SQLWARNn域提供了该问题的有用信息。
  ----试举一例,下面这条SELECT语句中带有数学表达式:
  ----SELECT empid,comm/salary INTO :hvempid, :hvcalc FROM EMPLOYEE
  ----如果在某一条记录碰上了数学异常,例如被0除,则返回代码-802。没有数据返回,也不知道是哪一条记录导致了该错误。但是,如果为数学表达式提供空值指示器宿主变量,改为:
  ----SELECT empid,comm/salary INTO :hvempid,:hvcalc :hvind FROM EMPLOYEE
  ----DB2将指示器变量设置为-2,并且返回SQLCODE为+802。这样程序将获得返回的empid,从而可以判断哪个雇员的记录造成了异常,程序也不需要终止。
  ----测试SQLWARN0是否为W也同样有用。例如,如果程序将字符串数据选取到宿主变量中,而该变量的长度不足以容纳整个字符串,则SQLCODE为+0,但数据被截断了。通过提供指示器变量可以解决这个问题,DB2把SQLWARN0设为W,SQLWARN1设为W,并且将指示器变量设为原始串的长度,通过使用指示器变量中的值就可以判断数据串的最大长度。
  SQLERRD(3)
  ----SQLERRD数组的第三项是SQLCA中最有用的域之一。当成功地完成了插入、更新或删除以后,该域被设置为插入、更新或删除的记录数。如果不知道SQLCA中含有这样的信息而程序又需要它,则不得不首先做一下COUNT。更糟糕的是,如果程序逻辑是将每一条记录选取到程序中,增加计数值,然后逐个地插入、更新或删除每一条记录,这样就丧失了集合操作的好处。这时最好的办法就是做SQL多记录插入、更新或删除,然后检查SQLERRD(3),获取需要的计数。
  ----然而也有例外的情况,首先,在SQL删除语句后,SQLERRD(3)并不包括DB2参照完整性而导致的级连删除的记录数。其次,从分段的表空间中海量删除(即DELETE语句无WHERE子名),在SQLERRD(3)以-1表示。因为DB2通过更新的记录表空间映射页来进行分段表空间的海量删除,实际的记录并未被读取,因此无法计数。除了这两个例外的情况,SQLERRD(3)可以用来节省DB2的读取操作。
  ----SQLCA共有24个域,详细内容可以参阅SQL参考手册的附录C,通过上述的例子说明,SQLCA中有用的域不仅是SQLCODE,灵活使用其他域,可以简化程序逻辑,减少DB2调用次数,从而提高程序性能。

论坛徽章:
0
2#
发表于 2006-3-29 16:34 | 只看该作者
感谢搂主

使用道具 举报

回复
招聘 : c/c++研发
论坛徽章:
45
技术图书徽章
日期:2014-03-10 14:09:192012新春纪念徽章
日期:2012-02-13 15:12:092012新春纪念徽章
日期:2012-02-13 15:12:092012新春纪念徽章
日期:2012-01-04 11:51:22ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15现任管理团队成员
日期:2011-05-07 01:45:082011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:152011新春纪念徽章
日期:2011-01-25 15:41:50
3#
发表于 2006-3-29 23:29 | 只看该作者
8错

使用道具 举报

回复
论坛徽章:
71
马上加薪
日期:2014-02-19 11:55:14ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412010广州亚运会纪念徽章:橄榄球
日期:2011-05-22 10:54:33管理团队成员
日期:2011-05-07 01:45:082011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:152011新春纪念徽章
日期:2011-01-25 15:41:502011新春纪念徽章
日期:2011-01-25 15:41:012010年世界杯参赛球队:丹麦
日期:2010-04-06 10:23:36
4#
发表于 2006-3-30 07:24 | 只看该作者
up

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表