超文本传输协议(HTTP)协议是最常用的Internet协议之一。 使用HTTP,可以通过统一资源定位器(URL)访问Web服务和其他在线信息资源。
通过将新的HTTP函数用作系统资源,DB2 for i为数据库开发人员开辟了一条新途径,以使数据库开发人员可以使用SQL合并Web服务。
新的HTTP用户定义函数(UDF)和用户定义表函数(UDTF)用Java™编写,它们存在于SYSTOOLS模式中。 SYSTOOLS与DB2 for i提供的其他模式不同,因为它不是缺省系统路径的一部分。 SYSTOOLS包含一组DB2 for i提供的示例和工具。 SYSTOOLS中的工具和示例被认为可以立即使用,但不属于任何IBM产品。 因此,它们不受IBM服务和支持的约束。
本文概述了新的HTTP函数,并提供了一个示例,展示了如何使用这些函数来请求Web服务并将数据结果与内置XML支持集成在一起,该内置XML支持也是DB2 for i 7.1支持的一部分。 该示例说明如何设计一个SQL查询,该查询从DB2 for i博客返回以前发布的条目。
为了对DB2 i 7.1使用HTTP功能,必须在系统上安装以下软件。
HTTP UDF和UDTF使用以下命名约定命名:
HTTP
method
表示HTTP函数。 支持所有常见的HTTP方法,包括POST
, GET
, PUT
, DELETE
和HEAD
。 有关HTTP方法的更多信息,可以参考参考资料部分中的超文本传输协议链接。 data-type
可以是CLOB
或BLOB
,它表示返回的HTTP响应消息的数据类型,或者在某些情况下(例如PUT
和POST
)表示请求消息的类型。 例如, HTTPPUTBLOBVERBOSE
是一个表函数,它将使用PUT
方法发送和接收BLOB数据,而HTTPGETCLOB
是一个标量函数,它将使用GET
方法来检索作为CLOB的资源表示形式。
除了HTTP方法功能之外,还提供了一些辅助功能来执行URL编码和解码以及base64编码和解码。 URL规范 (RFC 1738)定义了一组特殊字符,需要将这些特殊字符替换为转义序列(例如,如果用于URL的查询字符串中)。 辅助功能URLENCODE
和URLDECODE
执行URL编码和解码。 Base64编码通常用于将二进制数据编码为Web上的文本数据。 提供了辅助函数BASE64ENCODE
和BASE64DECODE
,用于对base64数据进行编码和解码。
表1显示了本文中使用的HTTP函数的签名。
功能名称 | ||
---|---|---|
httpGetBlobVerbose |
输入参数 | 输入参数类型 |
URL |
VARCHAR(2048) |
|
HTTPHEADER |
CLOB(10K) |
|
输出栏 | 输出列类型 | |
RESPONSEMSG |
BLOB(2G) |
|
RESPONSEHTTPHEADER |
CLOB(10K) |
|
httpGetBlob |
输入参数 | 输入参数类型 |
URL |
VARCHAR(2048) |
|
HTTPHEADER |
CLOB(10K) |
|
返回类型 | ||
BLOB(2G) |
||
urlEncode |
输入参数 | 输入参数类型 |
VALUE |
VARCHAR(2048) |
|
ENCODING |
VARCHAR(20) |
|
返回类型 | ||
VARCHAR(4096) |
对于URLENCODE
函数, VALUE
参数是原始字符串,而ENCODING
参数用于指定编码。 如果为VALUE
参数指定NULL
,则使用UTF-8。 RFC 3986建议使用UTF-8。
有关此示例中未使用的HTTP函数的列表,请参见参考资料小节中的白皮书。 您可以在以下位置找到集成文件系统下的HTTP函数的源代码:
/QIBM/ProdData/OS/SQLLIB/bin/systools_java_source.jar。
在本节中,提供了一个示例来说明如何使用HTTP函数从Web服务检索数据以及如何在关系数据库中处理检索到的数据以更好地使用。
图1显示了我们想从示例中的查询中检索到的结果集,该结果集是从DB2 for i Blog获得所需的条目。 结果集包含发布日期,作者,标题,响应(评论)数以及标识博客文章的URL。
此示例中的第一步是查阅需要访问的Web服务的应用程序编程接口(API)文档。 您可以参考该文档为DB2对我博客 .The文件告诉我们,HTTP GET
方法可以用来在特定时间后返回所有文章的列表,并为这个URL看起来应该如示例1所示。
http://db2fori.blogspot.com/feeds/posts/default?published-min=rfc3339_timestamp
在示例1中, rfc3339_timestamp
是RFC 3339标准描述的格式的时间戳。 RFC 3339时间戳的示例看起来像“ 2013-05-12T23:20:50.52Z”。
为了构造正确格式的时间戳,使用示例2中所示的UDF。 使用UDF使构造URL的代码更易于阅读。
CREATE FUNCTION rfc3339_ts_format(in_time TIMESTAMP)
RETURNS VARCHAR(26)
LANGUAGE SQL
SET OPTION DATFMT=*ISO
RETURN CONCAT( CONCAT(CAST(DATE(in_time) AS CHAR(10)),
'T' ),
CHAR(TIME(in_time), JIS));
现在可以使用示例3中所示SQL表达式来构造URL。在URL中指定参数数据时,最佳实践是利用SYSTOOLS.URLENCODE
标量函数。 该功能可以识别特殊字符,并在需要时添加转义字符。
CONCAT(CONCAT('http://db2fori.blogspot.com/feeds/posts/default?', 'published-min='),
SYSTOOLS.URLENCODE(rfc3339_ts_format(CURRENT_TIMESTAMP - 6 MONTHS),'UTF-8'))
下一步是设置请求标头。 DB2为我提供的XML内置功能使在SQL中处理XML数据变得容易。 博客Web服务支持使用基于XML的Atom格式检索数据。 因此,对请求标头进行了编码,以便响应采用Atom格式,如示例4所示。
此时,可以使用HTTPGETBLOBVERBOSE
表函数检索XML响应消息。 示例5显示了查询语句。
SELECT
XMLPARSE(DOCUMENT rs.responsemsg) msg,
rs.responsehttpheader
FROM TABLE(
SYSTOOLS.HTTPGETBLOBVERBOSE(
-- URL --
CONCAT(CONCAT('http://db2fori.blogspot.com/feeds/posts/default?','published-min=' ),
SYSTOOLS.URLENCODE(
rfc3339_ts_format(CURRENT_TIMESTAMP - 6 MONTHS),
'UTF-8'
)),
-- Header ---
'
')
) rs;
示例5中做出了一些重要的决定。
BLOB
。 通常,将BLOB
数据类型用于序列化XML数据而不是CLOB
是最佳实践,因为它避免了数据的字符集与XML文档中的编码声明不匹配的问题。 XMLPARSE
函数将BLOB
转换为XML值。 XML数据类型可以与SQL和XML函数(例如XMLTABLE
,这将在本示例的后面进行演示。 示例2中的查询结果集如图2所示RESPONSEHTTPHEADER
列包含HTTP响应代码"200"
,指示请求成功。
MSG列返回的XML结果的简化内容如示例6所示。
2013-07-22T14:57:00.000-05:00
A Competitive Advantage? It's all about the data.
Mike Cain
http://www.blogger.com/profile/01481223716996299215
[email protected]
0
…
……
RESPONSEHTTPHEADER
列返回的XML结果的简化内容如示例7所示。
OK
示例6中的XML文档不是很有帮助; 我们需要的是能够将XML文档分解或分解为关系数据库表, 如图1所示,以便更好地参考。
Web服务提供的文档说明了响应消息中XML文档的结构。 确定此信息的另一种方法是检查图2的MSG列中显示的文档。 在检查了示例文档之后,可以构造用于定位XML文档中有趣部分的XPath表达式。
XMLTABLE
函数可用于创建所需的结果集,如示例8所示。为简单起见,图8中使用了标量HTTPGETBLOB
函数,而不是示例5中使用的HTTPGETBLOBVERBOSE
表函数。 可以将这个查询写为HTTPGETBLOBVERBOSE
表函数和X MLTABLE
函数之间的HTTPGETBLOBVERBOSE
。 但是,此示例不使用HTTP响应标头,因此,标量函数就足够了。
SELECT published, author, title, responses, url
FROM
XMLTABLE(
--------------- Namespace declarations -------------
XMLNAMESPACES(
DEFAULT 'http://www.w3.org/2005/Atom',
'http://purl.org/syndication/thread/1.0' AS "thr"
),
--------------- Row expression --------------------
'feed/entry'
--------------- Initial context -------------------
PASSING
XMLPARSE(DOCUMENT
SYSTOOLS.HTTPGETBLOB(
-- URL --
CONCAT( CONCAT('http://db2fori.blogspot.com/',
'feeds/posts/default?published-min='),
SYSTOOLS.URLENCODE(
RFC3339_TS_FORMAT(CURRENT_TIMESTAMP - 6 MONTHS),
'UTF-8'
)),
-- header --
'
'
)
)
--------------- Result Set Columns ----------------
COLUMNS
published TIMESTAMP
PATH 'published',
author VARCHAR(15) CCSID 1208
PATH 'author/name',
title VARCHAR(100) CCSID 1208
PATH 'link[@rel="alternate" and
@type="text/html"]/@title',
responses INTEGER
PATH 'thr:total',
url VARCHAR(4096) CCSID 1208
PATH 'link[@rel="alternate" and
@type="text/html"]/@href'
) RS
ORDER BY PUBLISHED DESC
XMLTABLE
表函数具有几个重要组件。
XMLNAMESPACES
声明用于定义将在XPath表达式中使用的名称空间。 本示例为XPath表达式中使用的所有不合格元素设置默认名称空间“ http://www.w3.org/2005/Atom”,并将前缀“ thr”绑定到名称空间“ http:// purl” .org / syndication / thread / 1.0”。
行表达式表示结果集将为每个“ feed / entry”元素包含一行。
PASSING
子句定义用于评估行表达式的初始上下文。 在此示例中,在行表达式中使用的XPath表达式相对于从XMLPARSE
函数返回的XML文档的根。
所述HTTPGETBLOB
标量函数在内使用PASSING
子句的表达来检索响应消息。 HTTPGETBLOB
标量函数的参数与前面在图2中讨论的参数匹配。响应消息被解析为XML数据类型的实例(使用XMLPARSE
函数),并作为XMLTABLE
函数的参数提供。
COLUMNS
子句定义了XMLTABLE
函数产生的列。 每列都有一个名称,一个SQL数据类型和一个XPath表达式。 XPath表达式所标识的XML文档中的项目将转换为SQL数据类型,并分配给结果集的列。 路径表达式是相对于用于生成行的entry元素而言的。
示例8中的查询结果与图1中所示的结果集匹配。
DB2 for i HTTP函数提供了一种从SQL语句访问Web资源的简便方法。 当与DB2 for i内置XML支持结合使用时,它们提供了将Web服务直接无缝集成到数据库中的能力。 本文提供了一个示例,展示了HTTP函数从Web服务检索数据的基本用法以及如何将XML数据分解为关系数据。
翻译自: https://www.ibm.com/developerworks/ibmi/library/i-incorporating-web-service/index.html