2012-04-21 29 views
1

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

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

我有过程的伪代码,但不知道它将如何在DB2中看起来。

输入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 

请帮我创建上面的过程。我无法获得正确的ForEach语法,XML节点处理,DB2中的CURSOR和LOOPING。

ANSWER

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 
+0

什么是您的db2版本? – 2012-04-21 16:59:13

+0

我正在使用DB2 Express-C 9.7.5 – techknowfreak 2012-04-22 04:11:33

+0

感谢您展示适合您的答案。 – 2012-04-23 21:26:23

回答

0

DB2对XML数据的支持体面,所以你必须对如何将XML分解,并将其应用到一个或多个表的几个选项。

您正在寻找的功能是XMLTABLE。它是迄今为止将XML分解成单个表格结果集的最灵活的方法。

当传入的XML文档包含需要转到多个表的数据时,DECOMPOSE XML DOCUMENT语句功能强大,但它需要一个预注册的XML模式文档,其中包含特殊的注释,用于指定每个XML节点到其关系目标的映射。此声明不允许declared global temporary table(DGTT)充当目标表,当传入的XML数据需要在暂存DGTT中进行额外处理之后才能将其写入其最终目标,这一直是个问题。

至于基于光标的应用碎化数据的方法,您可以用一个使用XMLTABLE结果集作为输入表达式的单个MERGE语句替换整个循环。有很多关于使用DB2的MERGE语句处理“upsert”处理的示例,其中每个传入行都可能需要INSERT或UPDATE,具体取决于目标表中是否存在该主键。

+0

非常感谢!按照您的宝贵建议,我可以开展工作。 – techknowfreak 2012-04-23 15:31:46

+0

要更新100个这样的xml记录,sp大约需要1.5分钟。我认为这太长了..可能是什么原因?.. – techknowfreak 2012-04-23 15:58:14

+0

确保目标表正确编制了正在执行的更新,并且表具有准确的统计信息(通过RUNSTATS)。 DB2有一个解释实用程序,显示优化程序为查询选择的访问计划。在merge语句本身上使用explain实用程序比在整个存储过程上使用explain应用程序可能更容易。您通过explain实用程序运行的语句将受益于包含查询有效数据的硬编码XML文档。 – 2012-04-23 21:27:57