SQL的额外XML数据键值对

SQL的额外XML数据键值对,sql,sql-server,xml,Sql,Sql Server,Xml,下面是我试图从中提取的XML <?xml version="1.0" encoding="utf-16"?> <dictionary> <item> <key><string>MemberNumber</string></key> <value><string>66962336209</string></value> </item></dictio

下面是我试图从中提取的XML

<?xml version="1.0" encoding="utf-16"?>
<dictionary>
<item>
<key><string>MemberNumber</string></key>
<value><string>66962336209</string></value>
</item></dictionary>
创建表1 ID int identity1,1,extradata xml

INSERT INTO #1
Select '<dictionary><item><key><string>MemberNumber</string></key><value><string>66962336209</string></value></item></dictionary>'


SELECT extradata.value('/*:dictionary[1]/*:Item[1]/*:Key[1]','NVARCHAR(MAX)')
FROM #1;

select
    a.c.value('*:Value[1]','nvarchar(max)') as [value]
from #1 as t
    outer apply t.extradata.nodes('
        *:dictionary/*:Item[*:Key="code"]'
    ) as a(c)
我不断得到空值


我想获得两个不同行上的键值对,我可以从中转换数据。

您的SQL代码使用通配符名称空间,但示例XML没有。此外,XPath表达式完全关闭。 请尝试以下操作:

SQL


谢谢,这很有帮助。xml提取的新技术是将不同来源的代码组合在一起。还向其添加了密钥名称

DECLARE @tbl TABLE (ID INT IDENTITY(1,1) PRIMARY KEY, xml_data XML);
INSERT INTO @tbl (xml_data)
VALUES
(N'<dictionary>
    <item>
        <key>
            <string>MemberNumber</string>
        </key>
        <value>
            <string>66962336209</string>
        </value>
    </item>
</dictionary>');
-- DDL and sample data population, end

SELECT ID
    , col.value('(key/string/text())[1]','VARCHAR(30)') AS [key]
    , col.value('(value/string/text())[1]','VARCHAR(30)') AS [value]
FROM @tbl tbl
    CROSS APPLY tbl.[xml_data].nodes('/dictionary/item[key/string/text() = "MemberNumber"]') AS tab(col);

我想提出一个替代方案:

我方MCVE-+1对伊扎克·哈宾斯基的贡献:

DECLARE @tbl TABLE (ID INT IDENTITY(1,1) PRIMARY KEY, xml_data XML);
INSERT INTO @tbl (xml_data)
VALUES
(N'<dictionary>
    <item>
        <key>
            <string>MemberNumber</string>
        </key>
        <value>
            <string>66962336209</string>
        </value>
    </item>
</dictionary>');
-询问

选择t.ID ,t.xml_data.value'/dictionary /项[key/string/text=sql:variable@KeyName] /价值观 /串 /文本[1],“varchar30” 来自@tbl t -这不是强制性的,但可能会加快速度 -如果有许多项和许多行没有此键 其中t.xml_data.exist'/dictionary[item/key/string/text=sql:variable@KeyName]'=1; 简而言之:

我们声明要查找的密钥名称。这允许使用一个变量来获取apprach mor generic。 WHERE子句正在调用.exist。试试看。您不需要这个,但它可能会根据您的数据获得一些速度。 .value函数正在逐步转换为/dictionary/item,但使用谓词筛选其中一个,其中有一个具有给定名称的键。利用这一点,我们可以更深入地了解和阅读它的内容。
如果我得到的运算正确,他希望得到两列中的键和值。因此,只需将.nodes下放到/dictionary/item,然后是这两个节点的.value。。。可能是我弄错了…@Shnugo,让我们等待响应它被称为分解,即从XML数据类型转换为关系数据集。如果您想将各种节点作为派生集返回,这是一种很好的方法。在本例中,我将以典型的键值对的形式返回名称和值,并使用标准的SQL方法筛选此集合。但是,它看起来好像您正在为给定的名称读取一个值。这样做应该更快,而不需要.nodes。。。
DECLARE @tbl TABLE (ID INT IDENTITY(1,1) PRIMARY KEY, xml_data XML);
INSERT INTO @tbl (xml_data)
VALUES
(N'<dictionary>
    <item>
        <key>
            <string>MemberNumber</string>
        </key>
        <value>
            <string>66962336209</string>
        </value>
    </item>
</dictionary>');
-- DDL and sample data population, end

SELECT ID
    , col.value('(key/string/text())[1]','VARCHAR(30)') AS [key]
    , col.value('(value/string/text())[1]','VARCHAR(30)') AS [value]
FROM @tbl tbl
    CROSS APPLY tbl.[xml_data].nodes('/dictionary/item[key/string/text() = "MemberNumber"]') AS tab(col);
DECLARE @tbl TABLE (ID INT IDENTITY(1,1) PRIMARY KEY, xml_data XML);
INSERT INTO @tbl (xml_data)
VALUES
(N'<dictionary>
    <item>
        <key>
            <string>MemberNumber</string>
        </key>
        <value>
            <string>66962336209</string>
        </value>
    </item>
</dictionary>');
DECLARE @KeyName VARCHAR(100)='MemberNumber';