我有一些XML需要插入两个表中,即“产品”和“条形码”。 XML看起来像
<products>
<product>
<code>0001</code>
<name>Prod1</name>
<active>t</active>
<barcodes>
<barcode>0001666</barcode>
<barcode>6660001</barcode>
</barcodes>
<product>
<product>
... another one
</product>
和产品表由三个属性组成,条形码表是一个简单的条形码,产品代码元组与产品表有关系。我可以做类似的事情
insert into product (code, name, active) (
with products(prod_row) as (select-xml-column-from-table)
select
unnest(xpath('//product/code/text()', prod_row)),
unnest(xpath('//product/name/text()', prod_row)),
unnest(xpath('//product/active/text()', prod_row))
from products
);
它适用于产品,但是有没有一种明智的方法可以在同一条语句中用对产品代码的引用来填充条形码表?
顺便说一句。我一直找不到能够将其插入布尔“ active”(是否有任何指针)的类型转换?
预先感谢, 尼克
答案 0 :(得分:1)
测试XML:
<products>
<product>
<code>0001</code>
<name>Prod1</name>
<active>t</active>
<barcodes>
<barcode>0001666</barcode>
<barcode>6660001</barcode>
</barcodes>
</product>
<product>
<code>0002</code>
<name>Prod2</name>
<active>f</active>
<barcodes>
<barcode>0000420</barcode>
</barcodes>
</product>
</products>
查询:
WITH xmldata AS (
SELECT '<products><product><code>0001</code><name>Prod1</name><active>t</active><barcodes><barcode>0001666</barcode><barcode>6660001</barcode></barcodes></product><product><code>0002</code><name>Prod2</name><active>f</active><barcodes><barcode>0000420</barcode></barcodes></product></products>'::xml
), insert_products AS (
INSERT INTO products (code, name, active)
SELECT
unnest(xpath('//product/code/text()', xml)),
unnest(xpath('//product/name/text()', xml)),
unnest(xpath('//product/active/text()', xml))::text = 't'
FROM xmldata
RETURNING code -- 1
)
INSERT INTO barcodes (barcode, product_code)
SELECT
unnest(xpath('//barcode/text()', xd.barcodes)), -- 4
ip.code
FROM (
SELECT
unnest(xpath('//product/code/text()', xml))::text as code, -- 2
unnest(xpath('//product/barcodes', xml)) as barcodes
FROM xmldata
)xd
JOIN insert_products ip -- 3
ON xd.code = ip.code
借助CTE,可以创建两个链接的INSERT
语句。因此,您可以将代码作为第一条语句的RETURNING
值获取。
因此,您可以根据产品代码搜索正确的条形码,以创建第二个INSERT
语句的插入数据。
结果:
Table products:
code name active
0001 Prod1 t
0002 Prod2 f
----------------------
Table barcodes:
barcode product_code
0001666 0001
6660001 0001
0000420 0002
从技术上讲,如果产品插入物中没有任何过滤器,则可以保护连接部分的安全,因为在两个步骤中,您都在处理同一XML的全部数据。仅当您要过滤掉某些产品并且不想存储过滤出的条形码时,联接才有意义。
demo:db<>fiddle with join and filter
通知如何解决boolean
问题:
unnest(xpath('//product/active/text()', xml))::text = 't'
将XML内容转换为类型text
,并将其与您的TRUE
值进行比较。比较得出boolean
。
编辑:在您的情况下,这可以更简单地完成:您不需要进行比较,而只需进行第二次强制转换:
unnest(xpath('//product/active/text()', xml))::text::boolean
答案 1 :(得分:0)
-- TestQuery 使用示例数据从嵌套的 XML 中获取信息表
WITH xmldata AS ( SELECT '<products>
<product>
<code>A001</code>
<name>ProductA1</name>
<active>t</active>
</product>
<product>
<code>B002</code>
<name>ProductA2</name>
<active>f</active>
</product>
</products>'::xml)
SELECT unnest(xpath('//product/code/text()', xml)) as code,
unnest(xpath('//product/name/text()', xml)) as name,
unnest(xpath('//product/active/text()', xml))::text = 't' as status
FROM xmldata;