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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks

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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:13:40

利用基本原理构建基础

developerWorks



嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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


嵌入式 SQL 程序

DB2 提供了不同的编程方法,以便开发人员用来编写应用程序。其中最直接的一种方法是嵌入式 SQL 编程。此编程方法很直接,这是由于程序中嵌入了直接与 DB2 交互的 SQL 语句。可用下列任意一种支持的编程语言来编写程序:

  • C/C++
  • Java 语言 (SQLJ)
  • FORTRAN
  • COBOL
  • REXX


如何构造嵌入式 SQL 语句取决于所选的编程语言。C/C++ 和 FORTRAN 中的嵌入式 SQL 语句具有 EXEC SQL 关键字前缀:

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
	FROM employee WHERE deptno="OPERATIONS";

COBOL 中的嵌入式 SQL 语句与 C/C++ 中编码的类似,但是语句的末尾需加上关键字 END-EXEC

EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 
           FROM employee WHERE deptno="OPERATIONS" END-EXEC;

Java 语言中的嵌入式 SQL 语句与上述两种语言中的语句稍有不同,因为必须指定要执行该语句的连接上下文。下面是一个示例:

#sql [myConnCtx] {SELECT lastname, empid INTO :hostvar1, :hostvar2 
                    FROM employee WHERE deptno="OPERATIONS"};

为了更好地了解嵌入式 SQL 程序的形式,清单 8 包含了一小段用 C 编写的程序。在本系列的第四篇教程中(见 参考资料),将学习关于程序预编译和实际代码开发的更多信息。



                    int TbBasic(void)
{
  int rc = 0;
  struct sqlca sqlca;
	
  EXEC SQL BEGIN DECLARE SECTION;
    char hostVarStmt[50];
    EXEC SQL END DECLARE SECTION;
  
  /* declare cursor */
  EXEC SQL DECLARE c1 CURSOR FOR
    SELECT deptnumb, deptname FROM org WHERE deptnumb = 40;
	
  /* open cursor */
  EXEC SQL OPEN c1;
		
  /* fetch cursor */
  EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
					
  while (sqlca.sqlcode != 100)
  {
    printf("    %8d %-14s\n", deptnumb, deptname);
    EXEC SQL FETCH c1 INTO :deptnumb, :deptname;
  }
		
  /* close cursor */
  EXEC SQL CLOSE c1;
	  
  /* prepare the statement */
  strcpy(hostVarStmt, "DELETE FROM org WHERE deptnumb = 15");
  EXEC SQL PREPARE Stmt FROM :hostVarStmt;
	  
  /* execute the statement */
  EXEC SQL EXECUTE Stmt;
	  
  /* ROLLBACK the transaction */
  EXEC SQL ROLLBACK;
					
  return 0;
}





回页首


刚刚展示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。

示例中使用的 SELECT 语句阐释了静态 SQL 的用法。要编写静态 SQL,必须指定完整的语句。引用的表、列的名称以及数据类型是已知的。在运行时惟一可以指定的信息是使用主机变量的 SQL 语句的 WHERE 子句中的值。

静态 SQL 语句编译(使用 DB2 术语则为准备)后,生成数据访问计划并将其存储在数据库包中。调用包含该语句的应用程序时,将执行此包。由于没有语句需在运行时编译,所以执行静态 SQL 时没有编译成本。

在准备语句时,DB2 使用数据库统计信息和配置参数来计算并获得访问计划。随着数据库统计信息的更改,预生成的访问计划可能不如最初生成时那样理想。

使用准备静态 SQL 语句的用户的授权来创建包和将包绑定到数据库。只要执行包的用户拥有该包的 EXECUTE 权限,该用户就无需拥有包中所引用数据库对象的显式权限。参见下面标题为 “安全考虑” 的部分,了解关于 DB2 权限的更详细讨论。





回页首


动态 SQL 语句在运行时动态处理。执行应用程序时才需要知道语句结构。

请注意:清单 8 所示的示例 SQL 语句使用动态 SQL 来 PREPAREEXECUTE 一个 DELETE 语句。DELETE 语句中的文本存储在一个主机变量 hostVarStmt 中。PREPARE 语句后,就创建了该语句的可执行形式,并将其存储于数据库包中。一旦生成数据访问计划,即可 EXECUTE 准备后的语句。这听起来很熟悉,不是么?是的:这两个处理阶段与静态 SQL 语句几乎完全一样。惟一的不同是动态 SQL 在运行时处理 PREPAREEXECUTE。而静态 SQL 在预编译时准备访问计划并将其保存在数据库中。

动态 SQL 语句必须总是在执行前准备,无论是不是多次使用同一语句(因此,使用同一访问计划)。为了仅可能降低这些 PREPARE 的消耗,DB2 提供了包缓存(也称作动态查询缓存),用于将频繁使用访问计划保存在内存中。包缓存大大地降低了重复 SQL 准备请求的消耗,但仍然存在发出和响应准备请求的系统开销。

总是在准备语句时使用当前的数据库统计信息。因此,可生成最理想的数据访问路径。

SQL 语句的授权是在运行时决定。执行应用程序的用户必须拥有适当的权限,用来访问语句中所引用的数据库对象。下面将学习 DB2 权限的更详细内容。





回页首


要预编译嵌入式静态 SQL 程序,需拥有程序中所引用的数据库对象的显式权限。因为预编译或 PREPARE 阶段生成包并将其存储在数据库中,所以必须同时拥有 BINDADD 权限才能将新包添加到数据库中。要使用静态 SQL 执行程序,只需拥有相关包的 EXECUTE 权限即可。

如果要编译嵌入式动态 SQL 程序,还需拥有 BINDADD 权限。因为动态 SQL 不是在编译时准备,所以无需拥有其他权限。程序执行时,必须拥有发出每个 SQL 语句必需的所有权限,并对为嵌入式 SQL 程序所创建的包,拥有 EXECUTE 权限。

表 1 总结了预编译和执行只使用静态或纯动态 SQL 语句的程序所需的权限:



角色 静态 SQL 所需的权限 动态 SQL 所需的权限
开发人员(预编译程序) BINDADD 权限用于向数据库中添加新包;数据库对象的显式权限 BINDADD 权限用于向数据库中添加新包
应用程序用户(执行程序) EXECUTE 权限用于执行程序相关的包 数据库对象的显式权限;EXECUTE 权限用于执行程序相关的包





回页首


下面在表 2 中总结并扩展所了解的静态和动态 SQL 知识:



静态 SQL 动态 SQL
SQL 语句的结构是已知的。对列、表和数据类型的引用必须明确指定。变量只能用作语句的 WHERE 子句中的搜索值。 预编译时无需知道语句结构。语句文本自身可存储在应用程序执行期间引用的一个变量中。这就提供了支持程序的灵活性,因为在应用程序设计时并不知道语句的最终形式。
在预编译时生成数据访问计划。包在数据库中是持久的,并且可重用。如果只是偶尔运行语句,则与动态 SQL 相比,静态 SQL 可能提供更好的运行时性能。 在运行时生成数据访问计划。存储在内存中称为包缓存 的位置。如果多次执行同一语句,则可重用 PREPARE 阶段在内存中生成的数据访问计划。因此,动态 SQL 的性能不一定比静态 SQL 差。但是,首次执行动态 SQL 时必须承受 PREPARE 阶段的全部成本。
预编译时的数据库统计信息和配置参数用于生成理想的数据访问计划。 运行时的数据库统计信息和配置参数用于生成理想的数据访问计划 如果需要频繁地执行 RUNSTATS,则动态 SQL 可利用最新、最佳的数据库统计信息。
预编译时验证授权。开发人员要预编译包含静态 SQL 的程序,必须拥有访问语句中所引用的对象的适当授权和权限。创建包之后,执行包的用户必须拥有包的 EXECUTE 权限。 运行时验证授权。用户若要执行包含动态 SQL 的程序,必须对语句中所引用的对象拥有适当授权和权限。

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