SQL的额外XML数据键值对
下面是我试图从中提取的XMLSQL的额外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 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';