【问题标题】:Insert multiple records from xml从xml插入多条记录
【发布时间】:2014-12-18 19:47:05
【问题描述】:

我想批量插入到 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 中一样,但表是空的。

如果您注释掉“插入”行,您会看到这些值被正确解析。只是它返回单个记录,其中每列是一个数组,而不是返回多个记录。

我错过了什么?

【问题讨论】:

    标签: postgresql xpath


    【解决方案1】:

    好的,显然unnest 和数组索引是解决方案:

    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
    

    【讨论】:

      【解决方案2】:

      我希望在@: 之前删除一些多余的斜线

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-01
        • 2012-09-04
        • 2015-10-04
        • 2017-04-06
        • 1970-01-01
        相关资源
        最近更新 更多