Unnest (xpath()) 不能正确识别 NULL 值



PostgreSQL 版本 9.6,使用 xml2 扩展名。我正在尝试从XML中提取行并将它们插入到postgreSQL表中。下面是一个缩写示例:

ROLLBACK;
BEGIN;
DO $$
DECLARE 
v_xml xml;
v_record RECORD;
BEGIN
v_xml := '<?xml version="1.0" encoding="UTF-16"?>
<root>
<table>
<row><a>1</a><b>2</b><c>3</c></row>
<row><a></a><b>5</b><c>6</c></row>
<row><a>7</a><b>8</b><c>9</c></row> 
</table>
</root>'::text;
CREATE TEMPORARY TABLE temptable( col_a text, col_b text, col_c text ) ON COMMIT DROP;
INSERT INTO temptable VALUES
(
unnest(xpath('/root/table/row/a/text()', v_xml))::text,
unnest(xpath('/root/table/row/b/text()', v_xml))::text,
unnest(xpath('/root/table/row/c/text()', v_xml))::text
);
-- display table contents
FOR v_record IN SELECT * FROM temptable LOOP
RAISE NOTICE 'col_a: % col_b: % col_c: %', v_record.col_a, v_record.col_b, v_record.col_c;
END LOOP;
END $$;

当没有值为 NULL 时,这工作正常:

NOTICE:  col_a: 1 col_b: 2 col_c: 3
NOTICE:  col_a: 4 col_b: 5 col_c: 6
NOTICE:  col_a: 7 col_b: 8 col_c: 9

但是,对于缺失值或 NULL 值,unnest(( 无法正确识别它们,并使用其列数组的下一个值(应在下一行读取。

要进行演示,请按如下方式修改 XML(即将前 4 和 9 值设为空,或完全删除元素(:

<table>
<row><a>1</a><b>2</b><c>3</c></row>
<row><a></a><b>5</b><c>6</c></row>
<row><a>7</a><b>8</b><c></c></row>  
</table>

现在生成以下(错误(输出:

NOTICE:  col_a: 1 col_b: 2 col_c: 3
NOTICE:  col_a: 7 col_b: 5 col_c: 6
NOTICE:  col_a: 1 col_b: 8 col_c: 3
NOTICE:  col_a: 7 col_b: 2 col_c: 6
NOTICE:  col_a: 1 col_b: 5 col_c: 3
NOTICE:  col_a: 7 col_b: 8 col_c: 6

一些调试语句显示三个非嵌套列数组为 { 1, 7 }, { 2, 5, 8 } 和 { 3, 6 }。插入给定行时,没有用作列值的占位符 NULL。

有没有另一种方法可以实现取消嵌套,以正确考虑空或缺失的节点值?

这不是UNNEST的问题,而是(或者更确切地说,由于(xpath的问题,它似乎在返回的数组中不包含 NULL 值。

SELECT XPATH('/root/table/row/a/text()', '<root><table><row><a>1</a><a></a><a>3</a></row></table></root>'::XML)返回{1,3}

解决此问题的一种方法是先对元素进行xpath,然后再访问值:

SELECT (XPATH('/a/text()', u))[1]
FROM UNNEST(XPATH('/root/table/row/a', '<root><table><row><a>1</a><a></a><a>3</a></row></table></root>'::XML)) u

这将返回 3 行(第二行为 NULL(:

1
3

相关内容

最新更新