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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477867
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477868
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477869
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477870
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477871
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477872
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477873
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477874
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477875
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477876
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477877
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477878
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477869
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477880
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477881
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477882
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477883
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477884
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477885
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477886
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477887
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477889
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477890
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477891
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477892
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477893
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477884
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477895
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477896
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477897
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477898
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477899
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477900
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477901
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477902
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477903
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477904
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477905
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477906
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477907
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477908
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477899
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477910
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477911
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477912
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477913
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477914
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477915
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477917
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477918
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks

DB2 9 应用开发(733 考试)认证指南,第 3 部分: XML 数据操纵(7)-sdccf-ChinaUnix博客
  • 博客访问: 105477919
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-05-31 23:25:00

通过应用程序存储和检索 XML

developerWorks



SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181235) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181234) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181233) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181232) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181231) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181230) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181229) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181228) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181227) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181226) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181225) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181224) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181223) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181222) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181221) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181220) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181219) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181218) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181217) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181216) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181215) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181214) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181213) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181212) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181211) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181210) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181209) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181208) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181207) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181206) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181205) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181204) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181203) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181202) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181201) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181200) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181199) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181198) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181197) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181196) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181195) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181194) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181193) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181192) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181191) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181190) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181189) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181188) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181187) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181186) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181185) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~


SQL/XML 函数

XMLQUERY() 返回通过计算一个 XQuery 表达式得到的一个 XML 值,可能使用指定的输入参数作为 XQuery 变量。

这的确很简单。那么,它的实际意义是什么呢?XMLQUERY() 有两部分:

  • 一个 XQuery 表达式
  • 一个 PASSING 子句,在该子句中可以将数据传递给 XQuery 表达式

该函数的一个常见的用途是提取一个 XML 文档的一部分。一个表中的一个 XML 列(如果不为 null 的话)包含一个完整的 XML 文档。在一个 SELECT 列表中,如果选择 XML 列的列名,则得到整个 XML 文档。如果只想要整个文档的一部分,则可以使用 XMLQUERY()。对于 XQuery 表达式,可以使用一个简单的 XPath 表达式,例如 '$d/path1/path2/path3',或者使用一个完整的 FLWOR 表达式。$d 引用 PASSING 子句中的一个变量。 该子句允许将数据(列、表达式、文字)传递到 XQuery 表达式中。为了提取一个 XML 文档的一部分,将 XML 列名包括在 PASSING 子句中,并给定一个名称,例如 "d"。然后,XQuery 表达式就用 $d 引用那个列。

XMLEXISTS()SELECT 语句的 WHERE 子句中使用的一个谓词。它的语法类似于 XMLQUERY():它有一个 XQuery 表达式和一个 PASSING 子句。 和 XMLQUERY() 一样,XQuery 参数可以是一个简单的 XPath,或者是一个完整的 FLWOR 表达式。如果 XQuery 表达式返回至少一个项,则 XMLEXISTS() 返回 TRUE

XMLEXISTS() 通常用于测试一个 XML 文档(在 XML 列中)是否包含某些有趣的东西。有时候是一个特定的 XML 节点,一个属性,一个 XML 节点的特定的值,或者一个属性的特定的值。 可以测试多个条件。更有效的做法是用 XPath andor 将多个 XML 条件组合到一个 XMLEXISTS() 中,而不是多次调用 XMLEXISTS() 并使用 SQL ANDOR

很多 XML 查询可以用 XQuery 或 XMLQUERY() 来处理。两者之间有些不同:

  • XQuery 在结果序列中分行返回每个项。而 XMLQUERY() 是一个标量函数,并且是 SELECT 语句的一部分;它在每次被调用时只返回一个值(也就是说,对于传递给它的每个 XML 文档返回一个值)。如果一个 XML 文档中有多个项,那么 XMLQUERY() 必须能够在一行中返回这些项。因此,它返回一个序列,其中包含那个文档中的所有项。

  • 在 XQuery 中不能绑定参数或者使用主变量。 但是可以在 XMLQUERY()XMLEXISTS() 中用 PASSING 子句绑定参数或使用主变量。

  • 在 XQuery 中,XPath 表达式(例如 /path1/path2)在一步内同时履行应用谓词([] 标记)和投影(构造输出的元素列表)的角色。在 SELECT 语句中,将谓词应用到的角色由 XMLEXISTS() 负责;将谓词应用到一行中的节点以及投影的角色则由 XMLQUERY() 负责。通常,在一个 SQL/XML 查询中,相同的 XPath 谓词要指定两次,一次在 XMLEXISTS() 中,一次在 XMLQUERY() 中。

  • 为了将谓词应用到关系列,XQuery 使用 XPath 函数 db2-fn:sqlquery()。一个常规的含 XMLQUERY()SELECT 使用常规的 WHERE 子句,该子句将关系谓词与 XMLEXISTS() 混合在一起。

  • 只有 XMLQUERY() 可以在同一个 SELECT 列表中混合使用关系列和 XML 数据。

请参阅文章 "Query DB2 XML data with SQL"(developerWorks,2006 年 3 月),其中提供了 XMLQUERY()XMLEXISTS() 的详细的例子。





回页首


XMLELEMENT() 通过在某样东西 周围加上一个 XML 标记(例如 ),创建一个 XML 元素。某样东西 可以是任何 SQL 表达式(只要不是结构化类型),包括其它 XML 元素。 可选地,也可以包括名称空间和属性。必要时,例如被包括在 CHAR() 函数中,SQL 表达式将被自动转换成字符形式。

XMLATTRIBUTES() 在一个 XML 元素中创建一个或多个属性 (例如 )。该函数只能在 XMLELEMENT() 函数中使用。

XMLNAMESPACES() 为一个 XML 元素创建名称空间。该函数只能在 XMLELEMENT()XMLFOREST()XMLTABLE() 之类的其它函数中使用。



                    
SELECT XMLELEMENT( NAME "ColName", colname),
       XMLELEMENT( NAME "Type", typename)
FROM
       syscat.columns
WHERE
       tabschema = 'SYSCAT'
AND    tabname   = 'TABLES'
ORDER BY
       colno
;



                    
TABSCHEMA
        
VARCHAR
TABNAME
          
VARCHAR
OWNER
            
VARCHAR
TYPE
             
CHARACTER
STATUS
           
CHARACTER
BASE_TABSCHEMA
   
VARCHAR
BASE_TABNAME
     
VARCHAR
ROWTYPESCHEMA
    
VARCHAR
ROWTYPENAME
      
VARCHAR
CREATE_TIME
      
TIMESTAMP
INVALIDATE_TIME
  
TIMESTAMP
STATS_TIME
       
TIMESTAMP
COLCOUNT
         
SMALLINT
表ID
          
SMALLINT
TBSPACEID
        
SMALLINT



                    
SELECT XMLELEMENT
       (
         NAME "TableName",
         XMLATTRIBUTES
         (
           tableid  AS "TableId",
           colcount AS "NumCols"
         ),
         RTRIM(tabschema) || '.' || tabname
       )
FROM
       syscat.tables
WHERE
       type = 'T'
ORDER BY
       tableid
;



                    
表Id="2" NumCols="67">SYSIBM.SYSTABLES
表Id="2" NumCols="44">DB2QP.TRACK_QUERY_INFO
表Id="2" NumCols="3">TOOLS.REL_CAT_MEMBER
表Id="3" NumCols="41">SYSIBM.SYSCOLUMNS
表Id="3" NumCols="13">DB2QP.MANAGE_QUERY_INFO
表Id="3" NumCols="9">TOOLS.REL_TYPE
表Id="4" NumCols="57">SYSIBM.SYSINDEXES
表Id="4" NumCols="6">DB2QP.RESULT_INFO
表Id="4" NumCols="5">SYSTOOLS.POLICY
表Id="4" NumCols="8">TOOLS.REL_CAT
表Id="5" NumCols="9">SYSIBM.SYSCOLPROPERTIES
表Id="5" NumCols="23">DB2QP.QP_SYSTEM
表Id="5" NumCols="27">SYSTOOLS.HMON_ATM_INFO
表Id="5" NumCols="5">TOOLS.REL_LINK
表Id="6" NumCols="5">SYSIBM.SYSINDEXCOLUSE



                    
SELECT  XMLELEMENT
        (
          NAME "ColName",
          XMLNAMESPACES
          (
            DEFAULT ''
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
;



                    
xmlns="">TABSCHEMA
xmlns="">TABNAME
xmlns="">OWNER
xmlns="">TYPE
xmlns="">STATUS
xmlns="">BASE_TABSCHEMA
xmlns="">BASE_TABNAME
xmlns="">ROWTYPESCHEMA
xmlns="">ROWTYPENAME
xmlns="">CREATE_TIME
xmlns="">INVALIDATE_TIME
xmlns="">STATS_TIME
xmlns="">COLCOUNT
xmlns="">TABLEID
xmlns="">TBSPACEID



                    SELECT  XMLELEMENT
        (
          NAME "db2:ColName",
          XMLNAMESPACES
          (
            '/db2' AS "db2"
          ),
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
xmlns:db2="/db2">TABSCHEMA
xmlns:db2="/db2">TABNAME
xmlns:db2="/db2">OWNER
xmlns:db2="/db2">TYPE
xmlns:db2="/db2">STATUS
xmlns:db2="/db2">BASE_TABSCHEMA
xmlns:db2="/db2">BASE_TABNAME
<db2
:ColName 
xmlns:db2="/db2">ROWTYPESCHEMA
xmlns:db2="/db2">ROWTYPENAME
xmlns:db2="/db2">CREATE_TIME
xmlns:db2="/db2">INVALIDATE_TIME
xmlns:db2="/db2">STATS_TIME
xmlns:db2="/db2">COLCOUNT
xmlns:db2="/db2">TABLEID
xmlns:db2="/db2">TBSPACEID



                    
SELECT  XMLELEMENT(NAME "Table", tabname),
        XMLELEMENT(NAME "TbSpc1",
          tbspace
          OPTION EMPTY ON NULL
        ),
        XMLELEMENT(NAME "TbSpc2",
          tbspace
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
- COLUMNS
- COLUMNS_S
- REFERENTIAL_CONSTRAINTS
- REF_CONSTRAINTS
- TABLE_CONSTRAINTS
- TABLES
- TABLES_S
- USER_DEFINED_TYPES
- UDT_S
- VIEWS
- PARAMETERS
- PARAMETERS_S
- ROUTINES
- ROUTINES_S
-





回页首


XMLFOREST() 函数创建由一个或多个连在一起的 XML 元素组成的序列。 XMLELEMENT()XMLFOREST() 之间的不同点是:

  • XMLELEMENT() 只创建一个元素。而 XMLFOREST() 可以创建任意个连接在一起的元素。
  • 对于 XMLELEMENT(),XML 元素的名称是必需的,但是在 XMLFOREST() 中,对于简单的 SQL 表达式可以使用默认值。稍后的例子会演示这一点。
  • XMLELEMENT() 可以创建属性;XMLFOREST() 则不行。

XMLFOREST() 像是 XMLCONCAT()XMLELEMENT() 的组合(惟一不同的是 XMLFOREST() 不能指定属性)。该函数非常便于用来指定一系列的 XML 元素。

在这个例子中,注意 colnotypename 都为一个 XML 元素指定了名称,而 colname 则没有。如果忽略元素名称,则使用的名称与列名相同,不过是全部大写的。



                    
SELECT  XMLFOREST(
          colno    AS "ColNum",
          colname,
          typename AS "DataType"
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;



                    
0TABSCHEMAVARCHAR
1TABNAMEVARCHAR
2OWNERVARCHAR
3TYPECHARACTER
4STATUSCHARACTER
5BASE_TABSCHEMAVARCHAR
6BASE_TABNAMEVARCHAR
7ROWTYPESCHEMAVARCHAR
8ROWTYPENAMEVARCHAR
9CREATE_TIMETIMESTAMP
10INVALIDATE_TIMETIMESTAMP
11STATS_TIMETIMESTAMP
12COLCOUNTSMALLINT
13TABLEIDSMALLINT
14TBSPACEIDSMALLINT



                    
SELECT  XMLFOREST(
          XMLNAMESPACES(
            DEFAULT ''
          ),
          colno    AS "ColNum",
          colname
        )
FROM
        syscat.columns
WHERE
        tabschema = 'SYSCAT'
AND     tabname   = 'TABLES'
ORDER BY
        colno
FETCH FIRST 15 ROWS ONLY
;

清单 17. 例子 7 示例输出





                    
SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION EMPTY ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S



                    SELECT  XMLFOREST(
          tabname AS "Table",
          tbspace AS "TbSpc"
          OPTION NULL ON NULL
        )
FROM
        syscat.tables
WHERE
        tbspace IS NULL
FETCH FIRST 15 ROWS ONLY
;



                    
CHECK_CONSTRAINTS
COLUMNS
COLUMNS_S
REFERENTIAL_CONSTRAINTS
REF_CONSTRAINTS
TABLE_CONSTRAINTS
TABLES
TABLES_S
USER_DEFINED_TYPES
UDT_S
VIEWS
PARAMETERS
PARAMETERS_S
ROUTINES
ROUTINES_S





回页首


XMLCONCAT() 将两个或更多 XML 元素连接在一起。 这甚至包括 XMLCOMMENT()XMLTEXT()XMLPI() 等函数的输出。至少在两种情况下 XMLCONCAT() 非常有用:

  • 作为 XMLAGG() 函数的输入,XMLAGG() 函数只接受一个参数。
  • 构造混合节点(例如 John Q Smith



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Name", indname),
          XMLELEMENT(NAME "NumCols", colcount),
          XMLELEMENT(NAME "Uniq", uniquerule)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES012U
INDTABLES021D
INDTABLES031D
INDTABLES041D
INDTABLES054U
INDTABLES062D
INDTABLES072D
INDTABLES081D
INDCOLUMNS013U
INDCOLUMNS022D
INDCOLUMNS031D
INDINDEXES012U
INDINDEXES023U
INDINDEXES032D
INDINDEXES043D



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Index", indname),
          XMLTEXT(' has '),
          XMLELEMENT(NAME "NumCols", colcount)
        )
FROM
        syscat.indexes
FETCH FIRST 15 ROWS ONLY
;



                    
INDTABLES01 has 2
INDTABLES02 has 1
INDTABLES03 has 1
INDTABLES04 has 1
INDTABLES05 has 4
INDTABLES06 has 2
INDTABLES07 has 2
INDTABLES08 has 1
INDCOLUMNS01 has 3
INDCOLUMNS02 has 2
INDCOLUMNS03 has 1
INDINDEXES01 has 2
INDINDEXES02 has 3
INDINDEXES03 has 2
INDINDEXES04 has 3





回页首


SUM()MIN()MAX() 一样,XMLAGG() 是一个聚合函数。它接受一个 XML 表达式作为参数,对于每组记录,它将值都连接在一起。有一个可选的 ORDER BY 子句。当构建复杂的涉及一对多关系的 XML 文档时,XMLAGG() 非常有用。在下面的例子中, SYSCAT.INDEXES 的每一行都与 SYSCAT.INDEXCOLUSE 中的多个行组合在一起。 在将关系数据转换成 XML 时,众多嵌套的一对多关系可以用 XMLAGG() 来处理。



                    
WITH
t1 AS
(
  SELECT indschema,
         indname,
         colseq,
         XMLELEMENT(
           NAME "ColName",
           XMLATTRIBUTES(colseq AS "Seq"),
           colname
         ) AS xml_col
  FROM
         syscat.indexcoluse
),
t2 (indschema, indname, list_cols) AS
(
  SELECT indschema,
         indname,
         XMLAGG(xml_col ORDER BY colseq)
  FROM
         t1
  GROUP BY
         indschema,
         indname
)
SELECT  XMLELEMENT(
          NAME "Index",
          XMLATTRIBUTES(i.indname AS "Name"),
          t2.list_cols
        )
FROM
        syscat.indexes  I,
        t2              T2
WHERE
        i.colcount BETWEEN 2 AND 4
AND     t2.indschema = i.indschema
AND     t2.indname   = i.indname
FETCH FIRST 15 ROWS ONLY
;



                    
                    Row #1:


  SCHEMA
  NAME<


Row #2:


  HI_ID
  OBJ_NAME1
  OBJ_NAME2
  OBJ_NAME3


Row #3:


  TOWNER00
  TASKNAME00


Row #4:


  TASKID00
  SUFFIX00
  MODIFIED00


Row #5:


  TASKID00
  SUFFIX00


  • 这个例子可以用几种不同的方式来编写。公共表表达式用于分开代码,使之更清晰。另一种方法是嵌套很多层的函数,同时/或者使用子查询,这两种方法编写的代码都难于阅读。

  • 为了看上去比较清楚,示例输出在格式上作了调整(增加了缩进和换行)。

  • 这个例子只演示了一个一对多关系,但实际上可以处理很多一对多关系。

  • 第一个 CTE(公共表表达式) T1 获取用于子表(INDEXCOLUSE)的详细数据。

  • 第二个 CTE 是 T2,对于每个索引,它将来自 INDEXCOLUSE 的数据聚合成一行。通过在 XMLAGG() 中嵌套 XMLELEMENT(),可以在一条 SELECT 语句中一起完成 T1T2 的工作。这样易于管理,但是嵌套两层以上的函数很容易使代码难于阅读,难于排列匹配的括号。

  • 最后的 SELECTINDEXES 与聚合的来自 INDEXCOLUSE 的数据相连接,并用一个 XML 元素将它包装起来。





回页首


XMLDOCUMENT() 将一个 XML 节点转换成一个 XML 文档。XML 节点必须是格式良好的,这意味着它必须有一个根元素。含 XML 类型的列的表总是包含格式良好的 XML 文档。XMLQUERY() 函数返回 XML 节点(而不是文档)。需要 XMLDOCUMENT() 函数的主要场景是将 XMLQUERY() 的结果插入到一个含 XML 列的表中。例子 13 演示了这一点。



                    
CREATE TABLE demo.table1
(
  key          INT,
  xml_col      XML
)
;



                    
DB20000I  The SQL command completed successfully.



                    
INSERT INTO demo.table1 VALUES(1, 
'JoeSmith');



                    
DB20000I  The SQL command completed successfully.



                    
SELECT  XMLQUERY(
         '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
Joe



                    
INSERT INTO demo.table1
SELECT  2,
        XMLQUERY(
          '$d/person/first'
          PASSING xml_col AS "d"
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL20345N The XML value is not a well-formed document with a single root
element.  SQLSTATE=2200L



                    
INSERT INTO demo.table1
SELECT  2,
        XMLDOCUMENT(
          XMLQUERY(
            '$d/person/first'
            PASSING xml_col AS "d"
          )
        )
FROM
        demo.table1
WHERE
        key = 1
;



                    
DB20000I  The SQL command completed successfully.



                    
SELECT * FROM demo.table1;



                    
KEY  XML_COL
---- -------------------------------
  1  JoeSmith
  2  Joe





回页首


XMLTEXT() 创建一个文本节点。上面的例子 11 演示了如何使用该函数。它的主要用途是帮助创建混合类型的节点。





回页首


XMLCOMMENT() 创建一个注释节点。注释满足以下两个约束的字符串:

  • 不能包含两根连续的短横线(--
  • 不能用一根短横线(-)结尾



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Some comment'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad -- comments'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad -- comments" is not valid.
SQLSTATE=2200S



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLCOMMENT('Bad comments -'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20331N The XML comment value "Bad comments -" is not valid.  SQLSTATE=2200S





回页首


XMLPI() 创建一个 XML 处理指令。它的使用有两个限制:

  • PI 名称中任何地方都不能包含 xml,大写、小写以及大小写混合的形式都不行
  • 字符串中的任何地方都不能包含 ?>



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "ValidName", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
1200

hello



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "xmL", 'some string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20275N  The XML name "xmL" is not valid. Reason code = "5".  SQLSTATE=42634



                    
SELECT  XMLCONCAT(
          XMLELEMENT(NAME "Dummy1", 1200),
          XMLPI(NAME "Valid", 'bad ?> string'),
          XMLELEMENT(NAME "Dummy2", 'hello')
        )
FROM
        sysibm.sysdummy1
;



                    
SQL20332N The XML processing instruction value "bad ?> string" is not valid.
SQLSTATE=2200T
阅读(181184) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~