【问题标题】:Split XML field into multiple delimited values - SQL将 XML 字段拆分为多个分隔值 - SQL
【发布时间】:2022-11-17 02:43:24
【问题描述】:

我在一个字段中有一些 XML 内容;我想将每个 xml 字段拆分为多行。

XML 是这样的:

<env>
    <id>id1<\id>
    <DailyProperties>
        <date>01/01/2022<\date>
        <value>1<\value>
    <\DailyProperties>
    <DailyProperties>
        <date>05/05/2022<\date>
        <value>2<\value>
    <\DailyProperties>
<\env>

我想将所有内容放在表格中:

ID      DATE            VALUE
id1     01/01/2022      1
id1     05/05/2022      2

现在我设法解析了 xml 值,并且我在网上找到了一些东西可以将字符串分成多行 (like this),但我的字符串应该有某种分隔符。我这样做了:

SELECT
    ID,
    XMLDATA.X.query('/env/DailyProperties/date').value('.', 'varchar(100)') as r_date,
    XMLDATA.X.query('/env/DailyProperties/value').value('.', 'varchar(100)') as r_value
from tableX
outer apply xmlData.nodes('.') as XMLDATA(X)
WHERE ID = 'id1'

但我得到的所有值都没有分隔符,因此:

01/10/202202/10/202203/10/202204/10/202205/10/202206/10/202207/10/202208/10/202209/10/202210/10/2022

或者,如我的示例所示:

ID      R_DATE                  R_VALUE
id01    01/01/202205/05/2022    12

我发现 XQuery 有一个 last() 函数返回最后解析的值;在我的 xml 示例中,它将仅返回 05/05/2022,因此它应该存在一些用于解决添加定界符的问题。行数可能会有所不同,因为它可能会改变我具有值的天数。

【问题讨论】:

  • 不要将日期存储在文本列中。使用 DATE 数据类型并将日期转换为 YYYY/MM/DD,以便稍后在您的开发中使用
  • 这似乎不是 mysql;请标记您的实际数据库
  • 我只能查询数据库,我将在一个数据库中使用一个选择并将所有内容保存在另一个数据库中;当我达到一个单一的价值时,我会相应地投射。

标签: sql-server tsql xquery


【解决方案1】:

请尝试以下解决方案。

我必须修复您的 XML 以使其格式正确。

数据库

DECLARE @tbl TABLE (id INT IDENTITY PRIMARY KEY, xmldata XML);
INSERT INTO @tbl (xmldata) VALUES
(N'<env>
    <id>id1</id>
    <DailyProperties>
        <date>01/01/2022</date>
        <value>1</value>
    </DailyProperties>
    <DailyProperties>
        <date>05/05/2022</date>
        <value>2</value>
    </DailyProperties>
</env>');

SELECT p.value('(id/text())[1]','VARCHAR(20)') AS id
   , c.value('(date/text())[1]','VARCHAR(10)') AS [date]
   , c.value('(value/text())[1]','INT') AS [value]
FROM @tbl
CROSS APPLY xmldata.nodes('/env') AS t1(p)
   OUTER APPLY t1.p.nodes('DailyProperties') AS t2(c);

输出

id date value
id1 01/01/2022 1
id1 05/05/2022 2

【讨论】:

    【解决方案2】:

    Yitzhak 领先我 2 分钟。尽管如此,这就是我所拥有的:

    --==== XML Data:
    DECLARE @xml XML = 
    '<env>
      <id>id1</id>
      <DailyProperties>
        <date>01/01/2022</date>
        <value>1</value>
      </DailyProperties>
      <DailyProperties>
        <date>05/05/2022</date>
        <value>2</value>
      </DailyProperties>
    </env>';
    
    --==== Solution:
    SELECT 
      ID      = ff2.xx.value('(text())[1]','varchar(20)'),
      [Date]  = ff.xx.value('(date/text())[1]', 'date'),
      [Value] = ff.xx.value('(value/text())[1]', 'int')
    FROM        (VALUES(@xml))                   AS f(X)
    CROSS APPLY f.X.nodes('env/DailyProperties') AS ff(xx)
    CROSS APPLY f.X.nodes('env/id')              AS ff2(xx);
    

    退货:

    ID                   Date       Value
    -------------------- ---------- -----------
    id1                  2022-01-01 1
    id1                  2022-05-05 2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-16
      • 2016-07-25
      • 1970-01-01
      • 1970-01-01
      • 2019-09-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多