我希望批量插入到PostgreSQL数据库中:后端代码会创建类似
的XML<items>
<i dt="2014-08-01" name="vvv" count="12" />
<i dt="2014-08-02" name="zzz" count="6" />
</items>
我想传递给一个函数并一次性保存所有值。
但是我坚持xpath
:每个“列”似乎是一个值数组,我不知道如何将它们插入到表中。这是一个测试示例:
CREATE TEMP TABLE temp_values (dt date, name varchar, count int);
WITH x AS (SELECT '
<items>
<i dt="2014-08-01" name="vvv" count="12" />
<i dt="2014-08-02" name="zzz" count="6" />
<i dt="2014-08-03" name="bbd" count="10" />
</items>'::xml AS t
)
INSERT INTO temp_values
SELECT
xpath('/items/i/@dt', t),
xpath('/items/i/@name', t),
xpath('/items/i/@count', t)
FROM x;
现在,最后我希望temp_values
有3条记录,就像在XML中一样,但是表格是空的。
如果您注释掉“insert into”行,您会看到值已正确解析。它只是返回一个记录,其中每列是一个数组,而不是返回多个记录。
我错过了什么?
答案 0 :(得分:0)
好的,显然unnest
和数组索引是解决方案:
不要(数组)|将数组扩展为一组行
所以代码是
CREATE TEMP TABLE temp_values (dt date, name varchar, count int) ON COMMIT DROP;
WITH x AS (SELECT '
<items>
<i dt="2014-08-01" name="vvv" count="12" />
<i dt="2014-08-02" name="zzz" count="6" />
<i dt="2014-08-03" name="bbd" count="10" />
</items>'::xml AS t
)
INSERT INTO temp_values
SELECT
CAST(CAST((xpath('//@dt', node))[1] as varchar) as date),
CAST((xpath('//@name', node))[1] as varchar),
CAST(CAST((xpath('//@count', node))[1] as varchar) as int)
FROM (SELECT unnest(xpath('/items/i', t)) AS node FROM x) sub;
SELECT * FROM temp_values
答案 1 :(得分:0)
我更喜欢在@:
之前删除一些额外的斜杠CREATE TEMP TABLE temp_values (dt date, name varchar, count int) ON COMMIT DROP;
WITH x AS (SELECT '
<items>
<i dt="2014-08-01" name="vvv" count="12" />
<i dt="2014-08-02" name="zzz" count="6" />
<i dt="2014-08-03" name="bbd" count="10" />
</items>'::xml AS t
)
INSERT INTO temp_values
SELECT
CAST(CAST((xpath('@dt', node))[1] as varchar) as date),
CAST((xpath('@name', node))[1] as varchar),
CAST(CAST((xpath('@count', node))[1] as varchar) as int)
FROM (SELECT unnest(xpath('/items/i', t)) AS node FROM x) sub;
SELECT * FROM temp_values