【问题标题】:DB2 UPDATE stored proc looping through INPUT XMLDB2 UPDATE 存储过程通过 INPUT XML 循环
【发布时间】:2012-04-21 08:32:21
【问题描述】:

我是 DB2 和存储过程的新手。我想在 DB2 中编写一个存储过程来更新表。该过程有一个 XML 文档作为其输入参数。

我需要遍历 XML 的每条记录,选择一些节点并更新表中的相应行。此存储过程将用于批量更新表。

我有过程的伪代码,但不确定它在 DB2 中的外观。

INPUT XML 的格式为

<Root>
  <Record>
    <a>1234</a>
    <b>1</b>
    <c>2</c>
    <d>A</d>
    <e>B</e>
    <f>C</f>
  </Record>
<Record>
    <a>1235</a>
    <b>1</b>
    <c>2</c>
    <d>A</d>
    <e>B</e>
    <f>C</f>
  </Record>
</Root>

过程类似于

CREATE PROCEDURE UPDATE_BATCH (IN INDOC XML)
P1: BEGIN

FOR rec AS rec CURSOR FOR(
SELECT 
Record.XMLQUERY('//Record/a/text()') AS A, 
Record.XMLQUERY('//Record/b/text()') AS B,
Record.XMLQUERY('//Record/c/text()') AS C,
Record.XMLQUERY('//Record/d/text()') AS D,
Record.XMLQUERY('//Record/e/text()') AS E,
Record.XMLQUERY('//Record/f/text()') AS F
FROM
TABLE (INDOC)Record--Not Sure how to construct table from input xml
)
DO
UPDATE XYZ.TEMP_TABLE
SET ACOL=Record.A,
BCOL=Record.B,
CCOL=Record.C,
DCOL=Record.D,
ECOL=Record.E
WHERE
FCOL=Record.F;
END FOR;
END P1

请帮我创建上述程序。我无法在 DB2 中获得 ForEach、XML 节点处理、CURSOR 和 LOOPING 的正确语法。

回答

CREATE PROCEDURE UPDATE_BATCH(IN DOC XML)
BEGIN
MERGE INTO XYZ.TEMP_TABLE AS T
USING (SELECT X.* FROM 
XMLTABLE('$d/Root/Record' passing DOC as "d"
COLUMNS 
        "A" VARCHAR(10) PATH 'a',
        "B" VARCHAR(10) PATH 'b',
        "C" VARCHAR(10) PATH 'c',
        "D" VARCHAR(10) PATH 'd',
        "E" VARCHAR(10) PATH 'e',
        "F" VARCHAR(10) PATH 'f' 
) AS X) AS XT
ON T.FCOL=XT."F"
WHEN MATCHED THEN
UPDATE
SET
T.ACOL=XT."A",
T.BCOL=XT."B",
T.COL=XT."C"
END

【问题讨论】:

  • 你的 db2 版本是多少?
  • 我使用的是 DB2 Express-C 9.7.5
  • 感谢您提供适合您的答案。

标签: xml stored-procedures cursor db2 batch-processing


【解决方案1】:

Db2 对 XML 数据有很好的支持,因此您可以通过多种方式来分解 XML 并将其应用于一个或多个表。

您要查找的函数是XMLTABLE。这是迄今为止将 XML 分解为单个表格结果集的最灵活的方法。

当传入的 XML 文档包含需要转至多个表的数据时,DECOMPOSE XML DOCUMENT 语句功能强大,但它需要预先注册的 XML 模式文档 (XSD),其中包含指定每个输入的关系目标的特殊注释XML 节点。此外,DECOMPOSE XML DOCUMENT 语句只能写入永久表,而不能写入 declared global temporary tables (DGTT),后者通常用于在数据写入最终目的地之前暂存和调整数据。

至于使用游标来应用分解数据,您可以将整个循环替换为单个 MERGE 语句,该语句使用来自 XMLTABLE 的结果集作为输入表达式。有很多示例展示了如何使用 Db2 的 MERGE 语句进行“upsert”处理,其中每个传入的行可以由INSERTUPDATE 应用,具体取决于指定的键是否已存在于目标中表。

【讨论】:

  • 非常感谢!根据您的宝贵建议,我得到了它。
  • 要更新 100 条这样的 xml 记录,sp 大约需要 1.5 分钟。我认为它太长了..可能是什么原因?..
  • 确保为您正在执行的更新正确索引目标表,并且该表具有准确的统计信息(通过 RUNSTATS)。 DB2 有一个解释实用程序,它显示优化器为查询选择的访问计划。在合并语句本身上使用解释实用程序可能比在整个存储过程上更容易。您通过 explain 实用程序运行的语句将受益于包含有效查询数据的硬编码 XML 文档。
  • 是的。你是对的。实际上我加入了复合主键的一部分。当我为连接条件使用正确的列时,查询运行良好。现在更新 100 行需要几毫秒。再次感谢!
猜你喜欢
  • 1970-01-01
  • 2013-10-11
  • 2020-04-25
  • 1970-01-01
  • 2015-01-19
  • 1970-01-01
  • 2019-08-07
  • 1970-01-01
相关资源
最近更新 更多