如何在SQL Server中搜索XML

tmb3ates  于 2022-11-21  发布在  SQL Server
关注(0)|答案(2)|浏览(304)

我看了一些线程,但我认为我在Microsoft SQL Server(SSMS)中遗漏了一些东西。
我在列中将XML定义为XML数据类型,如下所示:
(* 我之前删除了一些东西,不确定是否需要 *)

<ItemGroupData ItemGroupOID="TEST" TransactionType="Insert">
    <ItemData ItemOID="TEACHER" Value="145"/>
    <ItemData ItemOID="AGE" Value="50" />
</ItemGroupData>
<ItemGroupData ItemGroupOID="TEST" TransactionType="Insert">
    <ItemData ItemOID="TEACHER" Value="151"/>
    <ItemData ItemOID="AGE" Value="42" /> 
</ItemGroupData>

我截断了一些内容,但是找到XML文件的最佳方式是什么?教师145所在的位置可以在任何Itemdata组中?
我可以找到它像:

SELECT 
    CAST(XML AS nvarchar(max)) AS test 
FROM
    table1 
WHERE
    XML LIKE '%14%'

但是我正在研究学习不同的方法而不是铸造,除非这是最优化的方法?

jmo0nnb3

jmo0nnb31#

SQL Server支持强大的XQuery语言来处理XML数据类型。
请尝试以下解决方案。
它使用XPath predicate [@Value=sql:variable("@TeacherValue")]直接在XML数据类型中搜索。
sql:variable("@TeacherValue")构造允许将参数传递给它。
此外,SQL Server还支持XML索引。

查询语句

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, XmlData XML);
INSERT INTO @tbl (XmlData) VALUES
(N'<root>
    <ItemGroupData ItemGroupOID="TEST" TransactionType="Insert">
        <ItemData ItemOID="TEACHER" Value="145"/>
        <ItemData ItemOID="AGE" Value="50"/>
    </ItemGroupData>
    <ItemGroupData ItemGroupOID="TEST" TransactionType="Insert">
        <ItemData ItemOID="TEACHER" Value="151"/>
        <ItemData ItemOID="AGE" Value="42"/>
    </ItemGroupData>
</root>');
-- DDL and sample data population, end

DECLARE @TeacherValue INT = 145;

SELECT t.ID
    , p.value('@ItemGroupOID', 'VARCHAR(50)') AS ItemGroupOID
    , p.value('@TransactionType', 'VARCHAR(50)') AS TransactionType
    , c.value('@ItemOID', 'VARCHAR(25)') AS ItemOID
    , c.value('@Value', 'INT') AS value
FROM @tbl AS t
CROSS APPLY XmlData.nodes('/root/ItemGroupData[ItemData[@ItemOID="TEACHER"
    and @Value=sql:variable("@TeacherValue")]]') AS t1(p)
CROSS APPLY t1.p.nodes('ItemData') AS t2(c);

输出

| 识别码|项组OID|交易类型|项目OID|价值观|
| - -|- -|- -|- -|- -|
| 一个|测试|插入|教师|一百四十五|
| 一个|测试|插入|年龄|五十个|

xmq68pz9

xmq68pz92#

是的,您删除的“stuff before”非常重要!您需要构建XPath表达式来从XML中选择各个片段--而这些表达式依赖于从根开始的所有内容!此外,您可能有在“stuff before”中定义的XML名称空间-您需要考虑这些名称空间才能获得任何结果。
Anyhoo - * 假设 * 在XML之前只有一个<root>....</root>节点,则可以得到如下所示的结果:

DECLARE @XmlTbl TABLE (ID INT NOT NULL, XmlData XML)

INSERT INTO @XmlTbl (ID, XmlData)
VALUES (1, 
    '<root><ItemGroupData ItemGroupOID="TEST" TransactionType="Insert">
    <ItemData ItemOID="TEACHER" Value="145"/>
    <ItemData ItemOID="AGE" Value="50" />
</ItemGroupData>
<ItemGroupData ItemGroupOID="TEST" TransactionType="Insert">
    <ItemData ItemOID="TEACHER" Value="151"/>
    <ItemData ItemOID="AGE" Value="42" /> 
</ItemGroupData></root>')

SELECT
    t.ID,
    XC.value('(@ItemGroupOID)', 'varchaR(50)') AS ItemGroupOID,
    XC.value('(@TransactionType)', 'varchaR(50)') AS TransactionType,
    XC2.value('@ItemOID', 'varchar(25)') AS ItemOID,
    XC2.value('@Value', 'int') AS value
FROM
    @XmlTbl t
CROSS APPLY    -- "enumerate" the <ItemGroupData> nodes under <root>
    XmlData.nodes('/root/ItemGroupData') AS XT(XC)
CROSS APPLY    -- "enumerate" the <ItemData> subnodes
    XC.nodes('ItemData') AS XT2(XC2)
WHERE
    XC.value('(ItemData/@Value)[1]', 'int') = 145

这将返回以下结果:
| 识别码|项组OID|交易类型|项目OID|价值|
| - -|- -|- -|- -|- -|
| 一个|测试|插入|教师|一百四十五|
| 一个|测试|插入|年龄|五十个|

相关问题