如何在 SQL 语句中获取 XML 值?

Posted

技术标签:

【中文标题】如何在 SQL 语句中获取 XML 值?【英文标题】:How to get XML values in SQL statement? 【发布时间】:2020-05-11 09:57:56 【问题描述】:

下面是 XML 标记,我需要从中获取值并将其形成为 SQL 输出,我遇到了一些问题,

<xml>
    <Channel>
        <Program id="1" category="A">
            <name>PraMatino</name>
            <Bin>
                <Date>1/1/2020</Date>
                <Date>1/1/2020</Date>
            </Bin>
            <Player>
                <Pla>Rajesh</Pla>
                <Pla>Suman</Pla>
            </Player>
            <Television>
                <HostDeails>2/9/2020</HostDeails>
                <HostDeails>MALE</HostDeails>
                <HostDeails>Colour</HostDeails>
            </Television>
            <addresses>
                <address>
                    <address1>No 10</address1>
                    <city>Chennai</city>
                    <country>IN</country>
                    <ProductName>Lavender</ProductName>
                </address>
                <address>
                    <address1>N0 72</address1>
                    <city>Sanagoor Road</city>
                    <postalCode>641006</postalCode>
                </address>
                <address>
                    <address1>Old No 10/ New No 3</address1>
                    <city>Madurai</city>
                    <country>IN</country>
                    <ProductName>Lavender</ProductName>
                </address>
                <address>
                    <address1>N0 98</address1>
                    <city>BridhSanagoor Road</city>
                    <country>SriLanka</country>
                    <postalCode>641006</postalCode>
                </address>
            </addresses>
        </Program>
        <Program id="25" category="B">
            <name>Rahman</name>
            <Bin>
                <Date>10/1/2020</Date>
                <Date>1/12/1989</Date>
            </Bin>
            <Player>
                <Pla>Paul</Pla>
                <Pla>Right</Pla>
            </Player>
            <Television>
                <HostDeails>5/7/2021</HostDeails>
                <HostDeails>MALE</HostDeails>
                <HostDeails>Colour</HostDeails>
            </Television>
            <addresses>
                <address>
                    <address1>S7</address1>
                    <city>Coimbatire</city>
                    <country>IN</country>
                    <ProductName>Lavender</ProductName>
                </address>
                <address>
                    <address1>Sai Akshya Appartment</address1>
                    <city>Sanagoor Road</city>
                    <postalCode>631009</postalCode>
                </address>
                <address>
                    <address1> No 3</address1>
                    <city>Thenkaasi</city>
                    <ProductName>Lavender</ProductName>
                </address>
                <address>
                    <address1>N0 98</address1>
                    <city>BridhSanagoor Road</city>
                    <country>SriLanka</country>
                    <postalCode>641006</postalCode>
                </address>
            </addresses>
        </Program>
    </Channel>
</xml>

如何将上面的 XML 查询到下面的 SQL 选择语句中?

我可以实现“ADDRESS1”和“CITY”,但如果我尝试在“ADDRESSES”中包含“ID”和“CATEGORY”标签,它不会按预期工作。欢迎分享你的想法

谢谢

【问题讨论】:

您需要指定您的数据库供应商。 【参考方案1】:

您没有指定数据库供应商。请尝试以下 SQL。它适用于 MS SQL Server。它通过CROSS APPLY 子句和不同的别名模拟XML 内部的一对多关系。

SQL

DECLARE @xml XML = 
N'<xml>
    <Channel>
        <Program id="1" category="A">
            <name>PraMatino</name>
            <Bin>
                <Date>1/1/2020</Date>
                <Date>1/1/2020</Date>
            </Bin>
            <Player>
                <Pla>Rajesh</Pla>
                <Pla>Suman</Pla>
            </Player>
            <Television>
                <HostDeails>2/9/2020</HostDeails>
                <HostDeails>MALE</HostDeails>
                <HostDeails>Colour</HostDeails>
            </Television>
            <addresses>
                <address>
                    <address1>No 10</address1>
                    <city>Chennai</city>
                    <country>IN</country>
                    <ProductName>Lavender</ProductName>
                </address>
                <address>
                    <address1>N0 72</address1>
                    <city>Sanagoor Road</city>
                    <postalCode>641006</postalCode>
                </address>
                <address>
                    <address1>Old No 10/ New No 3</address1>
                    <city>Madurai</city>
                    <country>IN</country>
                    <ProductName>Lavender</ProductName>
                </address>
                <address>
                    <address1>N0 98</address1>
                    <city>BridhSanagoor Road</city>
                    <country>SriLanka</country>
                    <postalCode>641006</postalCode>
                </address>
            </addresses>
        </Program>
        <Program id="25" category="B">
            <name>Rahman</name>
            <Bin>
                <Date>10/1/2020</Date>
                <Date>1/12/1989</Date>
            </Bin>
            <Player>
                <Pla>Paul</Pla>
                <Pla>Right</Pla>
            </Player>
            <Television>
                <HostDeails>5/7/2021</HostDeails>
                <HostDeails>MALE</HostDeails>
                <HostDeails>Colour</HostDeails>
            </Television>
            <addresses>
                <address>
                    <address1>S7</address1>
                    <city>Coimbatire</city>
                    <country>IN</country>
                    <ProductName>Lavender</ProductName>
                </address>
                <address>
                    <address1>Sai Akshya Appartment</address1>
                    <city>Sanagoor Road</city>
                    <postalCode>631009</postalCode>
                </address>
                <address>
                    <address1>No 3</address1>
                    <city>Thenkaasi</city>
                    <ProductName>Lavender</ProductName>
                </address>
                <address>
                    <address1>N0 98</address1>
                    <city>BridhSanagoor Road</city>
                    <country>SriLanka</country>
                    <postalCode>641006</postalCode>
                </address>
            </addresses>
        </Program>
    </Channel>
</xml>';

SELECT prog.c.value('@id','INT') AS id
    , prog.c.value('@category','CHAR(1)') AS category
    , addr.c.value('(address1/text())[1]','VARCHAR(100)') AS address1
    , addr.c.value('(city/text())[1]','VARCHAR(100)') AS city
FROM @xml.nodes('/xml/Channel/Program') AS prog(c)
    CROSS APPLY prog.c.nodes('addresses/address') AS addr(c);

输出

+----+----------+-----------------------+--------------------+
| id | category |       address1        |        city        |
+----+----------+-----------------------+--------------------+
|  1 | A        | No 10                 | Chennai            |
|  1 | A        | N0 72                 | Sanagoor Road      |
|  1 | A        | Old No 10/ New No 3   | Madurai            |
|  1 | A        | N0 98                 | BridhSanagoor Road |
| 25 | B        | S7                    | Coimbatire         |
| 25 | B        | Sai Akshya Appartment | Sanagoor Road      |
| 25 | B        | No 3                  | Thenkaasi          |
| 25 | B        | N0 98                 | BridhSanagoor Road |
+----+----------+-----------------------+--------------------+

【讨论】:

以上是关于如何在 SQL 语句中获取 XML 值?的主要内容,如果未能解决你的问题,请参考以下文章

用sql语句如何获取当前时间,如何通过写sql语句改变数据库中的值如何通过写sql语句把数据从数据中提取出来

java语句如何获取XML文件的节点值

在ibatis和mysql环境下使用insert如何获取返回值

SQL Select 语句:如何从表“M”中获取所有值以及从表“T”中获取任何相关值,如果没有,则为 0

如何从“for xml path”获取结果?

oracle中如何获取最后执行的SQL语句并绑定变量值