Chinaunix首页 | 论坛 | 博客
  • 博客访问: 91260646
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260647
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260648
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260649
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260650
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260651
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260652
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260653
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260644
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260655
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260656
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260657
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260658
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260659
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260660
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260661
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260662
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260663
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260664
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260665
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260666
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260667
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260668
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260659
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260670
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260671
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260672
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260673
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260674
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260675
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260676
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260677
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260678
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260679
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260680
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260681
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260682
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260683
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260674
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260685
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260686
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260687
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260688
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260689
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260690
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260691
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260692
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260693
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260694
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260695
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260696
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 4 部分: 嵌入式 SQL 编程(4)-sdccf-ChinaUnix博客
  • 博客访问: 91260697
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:29:12

构建与 DB2 进行交互的应用程序

developerWorks



诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272374) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272373) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272372) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272371) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272370) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272369) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272368) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272367) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272366) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272365) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272364) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272363) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272362) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272361) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272360) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272359) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272358) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272357) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272356) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272355) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272354) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272353) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272352) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272351) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272350) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272349) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272348) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272347) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272346) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272345) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272344) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272343) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272342) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272341) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272340) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272339) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272338) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272337) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272336) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272335) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272334) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272333) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272332) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272331) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272330) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272329) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272328) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272327) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272326) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272325) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272324) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


诊断和错误处理

在前面,我们了解到 SQLCA 数据结构包含每当执行 SQL 语句时由 DB2 Database Manager 更新的元素集合。指派给该结构中 sqlcode 元素的值表示该 SQL 语句是执行成功还是失败(值为 0 表示执行成功,正值表示执行成功但带有警告,而负值表示发生了错误)。在执行 SQL 语句之后,嵌入式 SQL 应用程序至少应该立即检查所产生的 sqlcode 值(通常称作 SQL 返回码)。如果 SQL 语句未能按预期执行,就应该通知用户发生了错误或警告;另外,只要条件允许,就应该给他们提供足够的诊断信息,以便他们定位并解决问题。

正如您能想像到的,在执行每个 SQL 语句之后都检查 SQL 返回码可能给应用程序增加额外的开销,尤其当应用程序包含大量 SQL 语句时。但是,因为嵌入式 SQL 应用程序源代码文件中编写的每个 SQL 语句都必须由 SQL 预编译器来处理,所以可以让预编译器自动生成用以检查 SQL 返回码的源代码。这是通过在源代码文件中嵌入一种或多种形式的 WHENEVER SQL 语句来完成的。

WHENEVER 语句让预编译器生成源代码,用以在发生错误、警告或缺少数据时评估 SQL 返回码并转移到指定的标号。(如果未使用 WHENEVER 语句,默认行为是忽略 SQL 返回码,好像未曾碰到问题一样继续进行处理。)可以使用四种 WHENEVER 语句形式,其中三种 WHENEVER 语句分别用于检查三种不同类型的错误/警告情况,还有一种用于关闭错误检查:

  • WHENEVER SQLERROR GOTO [Label]:指示预编译器生成源代码,用以在生成负的 sqlcode 值时评估 SQL 返回码并转移到指定标号。

  • WHENEVER SQLWARNING GOTO [Label]:指示预编译器生成源代码,用以在生成正的 sqlcode 值(除了值 100 之外)时评估 SQL 返回码并转移到指定标号。

  • WHENEVER NOT FOUND GOTO [Label]:指示预编译器生成源代码,用以在生成为 100sqlcode 值或为 02000sqlstate 值时评估 SQL 返回码并转移到指定标号。(100 值用来表示没有找到与指定的选择条件匹配的记录,或者已经到达了结果数据集的末尾。)

  • WHENEVER [SQLERROR | SQL WARNING | NOT FOUND] CONTINUE:指示预编译器忽略 SQL 返回码,继续处理应用程序中的下一个指令。

源代码文件可以包含这四种形式的 WHENEVER 语句的任意组合,而且前三种形式的出现次序是无关紧要的。但是,一旦使用了任一形式的 WHENEVER 语句,就将评估并相应地处理随后执行的所有 SQL 语句的 SQL 返回码,直到应用程序结束或另一个 WHENEVER 语句更改该行为。

清单 8 给出了一个用 C 编程语言编写的示例,它说明了如何使用 WHENEVER 语句来捕捉和处理缺少数据的错误:



                     
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;

// Set Up Error Handler
EXEC SQL WHENEVER NOT FOUND GOTO NOT_FOUND_HANDLER;

// Connect To The Appropriate Database 
EXEC SQL CONNECT TO sample USER db2admin USING ibmdb2;     
     
// Execute A SELECT INTO SQL Statement (If A "DATA NOT FOUND" Situation Occurs, 
// The Code Will Branch To The NOT_FOUND_HANDLER Label)
EXEC SQL SELECT empno INTO :EmployeeNo 
    FROM rsanders.employee
    WHERE job = 'CODER';
...

// Disable All Error Handling
EXEC SQL WHENEVER NOT FOUND CONTINUE;

// Prepare To Return To The Operating System
goto EXIT;
 
// Define A Generic "Data Not Found" Handler    
NOT_FOUND_HANDLER:
    printf("NOT FOUND: SQL Code = %d\n", sqlca.sqlcode);
    EXEC SQL ROLLBACK;
    goto EXIT;

EXIT:
    
// Terminate The Database Connection
EXEC SQL CONNECT RESET;
       
// Return Control To The Operating System
return(0);	
        

遗憾的是,在使用 WHENEVER SQL 语句时所生成的代码依赖于 GO TO 跳转,而不是通过调用/返回接口将控制转移到适当的错误处理段。因此,当将控制传递给用于处理错误和警告的源代码时,应用程序既无法知道控制来自何处,也无法知道在正确处理错误或警告之后,应将控制返回到何处。因此,在将控制传递给 WHENEVER 语句错误处理标号时,应用程序可以做的惟一一件事就是显示生成的错误代码,回滚当前事务并将控制返回给操作系统。





回页首


除了其他东西之外,DB2 的大多数版本还包含一组功能丰富的称为管理 API(应用程序编程接口)的函数。这些 API 用来在 SQL 提供给 DB2 应用程序的数据存储、操纵和检索功能之外提供额外的服务。实际上,任何可以从命令行处理器通过执行 DB2 命令来执行的数据库操作,都可以通过在应用程序中调用适当的管理 API 来执行。

在每次执行 SQL 语句时,指派给 SQLCA 数据结构变量的 sqlcode 元素的值实际上都是一个编码数字。一个专门的管理 API 可以将这个编码数字转换成一个可以显示给用户的有意义的描述。该 API 被称为 Get Error Message API。在 C/C++ 高级编程语言源代码文件中,用于调用这个 API 的基本语法如下:

sqlaintp (char          *pBuffer,
          short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA);

以下是其他高级编程语言源代码文件中用来调用这个 API 的语法:

sqlgintp (short         sBufferSize,
          short         sLineWidth,
          struct sqlca  *pSQLCA,
          char          *pBuffer);
	

让我们更详细地查看这个 API 语法中的各个成分:

  • pBuffer:指定 Get Error Message API 在内存中存储任何检索出的消息文本的位置。

  • sBufferSize:指定应将所检索的消息文本写入的内存缓冲区的大小(以字节为单位)。

  • sLineWidth:指定在换行符之间一行消息文本可以包含的最大字符数。值为 0 表示所返回的整个消息文本不带换行符。

  • pSQLCA:指定 SQLCA 数据结构变量在内存中的存储位置。

每当调用 Get Error Message API 时,所提供的 SQLCA 数据结构变量的 sqlcode 元素中存储的值用来定位和检索一个消息文件中适当的错误消息文本,该消息文件是与 DB2 打包在一起的。清单 9 是一个用 C 编程语言编写的示例,它说明了通常如何使用 Get Error Message API 获得和显示与所生成的 SQL 返回码相关联的消息。



                             
	
...
// Include The SQLCA Data Structure Variable
EXEC SQL INCLUDE SQLCA;
    
// Declare The Local Memory Variables
long  RetCode = SQL_RC_OK;
char  ErrorMsg[1024];
...

// Perform Some SQL Operation    
...
     
// If An Error Occurred, Obtain And Display Any Diagnostic Information Available
if (sqlca.sqlcode != SQL_RC_OK)
{ 
    // Retrieve The Error Message Text For The Error Code Generated
    RetCode = sqlaintp(ErrorMsg, sizeof(ErrorMsg), 70, &sqlca);
    switch (RetCode)
    {
    case -1:
        printf("ERROR : Insufficient memory.\n");
        break;
    case -3:
        printf("ERROR : Message file is inaccessible.\n");
        break;
    case -5:
        printf("ERROR : Invalid SQLCA, bad buffer, ");
        printf("or bad buffer length specified.\n");
        break;
    default:
        printf("%s\n", ErrorMsg);
        break;
    }
}
...	
	

正如在这个示例中看到的,在调用 Get Error Message API 时,它返回一个表明执行是否成功的值。在这个示例中,检查所产生的返回码;如果出现了错误,将向用户返回一个消息以解释 API 为何失败。如果 API 成功了,则将检索到的消息文本返回给用户。





回页首


除了 SQL 返回码之外,DB2(以及其他关系数据库产品)还使用一组称为 SQLSTATE 的错误消息编码来为警告和错误提供补充诊断信息。SQLSTATE 是由字母数字组成的五个字符(字节)的字符串,其格式为 ccsss,其中 cc 表示错误消息类,而 sss 表示错误消息子类。与 SQL 返回码的值一样,每当执行 SQL 语句时,就将 SQLSTATE 的值写入所使用的 SQLCA 数据结构变量的一个元素(sqlstate 元素)中。而且,正如 Get Error Message API 可以将生成的任何 SQL 返回码值转换成有意义的描述一样,另一个 API —— Get SQLSTATE Message API —— 也可以将 SQLSTATE 值转换成有意义的描述。通过在嵌入式 SQL 应用程序中包含其中一个 API(或两个均包含),就可以在发生错误和/或警告情况时,向最终用户返回有意义的信息。

阅读(272323) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~