Lar*_*nal 103 xml sql-server xpath
只看我的XML字段,我的行看起来像这样:
<person><firstName>Jon</firstName><lastName>Johnson</lastName></person>
<person><firstName>Kathy</firstName><lastName>Carter</lastName></person>
<person><firstName>Bob</firstName><lastName>Burns</lastName></person>
Run Code Online (Sandbox Code Playgroud)
请注意,这些是我表中的三行.
我想将SQL结果作为表返回
Jon | Johnson
Kathy| Carter
Bob | Burns
Run Code Online (Sandbox Code Playgroud)
什么查询将完成此任务?
Lar*_*nal 150
鉴于XML字段名为'xmlField'...
SELECT
[xmlField].value('(/person//firstName/node())[1]', 'nvarchar(max)') as FirstName,
[xmlField].value('(/person//lastName/node())[1]', 'nvarchar(max)') as LastName
FROM [myTable]
Run Code Online (Sandbox Code Playgroud)
Rem*_*anu 116
考虑到XML数据来自表'table'并存储在列'field'中:使用XML方法,提取值xml.value(),项目节点xml.nodes(),用于CROSS APPLY连接:
SELECT
p.value('(./firstName)[1]', 'VARCHAR(8000)') AS firstName,
p.value('(./lastName)[1]', 'VARCHAR(8000)') AS lastName
FROM table
CROSS APPLY field.nodes('/person') t(p)
Run Code Online (Sandbox Code Playgroud)
你可以抛弃nodes(),cross apply如果每个字段只包含一个元素'person'.如果XML是您选择的变量FROM @variable.nodes(...)而您不需要cross apply.
小智 16
这篇文章有助于解决我的问题,它有一些不同的XML格式......我的XML包含一个键列表,如下例所示,我将XML存储在名为DeleteBatch的表中的SourceKeys列中:
<k>1</k>
<k>2</k>
<k>3</k>
Run Code Online (Sandbox Code Playgroud)
创建表并使用一些数据填充它:
CREATE TABLE dbo.DeleteBatch (
ExecutionKey INT PRIMARY KEY,
SourceKeys XML)
INSERT INTO dbo.DeleteBatch ( ExecutionKey, SourceKeys )
SELECT 1,
(CAST('<k>1</k><k>2</k><k>3</k>' AS XML))
INSERT INTO dbo.DeleteBatch ( ExecutionKey, SourceKeys )
SELECT 2,
(CAST('<k>100</k><k>101</k>' AS XML))
Run Code Online (Sandbox Code Playgroud)
这是我从SQL中选择键的SQL:
SELECT ExecutionKey, p.value('.', 'int') AS [Key]
FROM dbo.DeleteBatch
CROSS APPLY SourceKeys.nodes('/k') t(p)
Run Code Online (Sandbox Code Playgroud)
这是查询结果......
ExecutionKey Key 1 1 1 2 1 3 2 100 2 101
这可以回答你的问题:
select cast(xmlField as xml) xmlField into tmp from (
select '<person><firstName>Jon</firstName><lastName>Johnson</lastName></person>' xmlField
union select '<person><firstName>Kathy</firstName><lastName>Carter</lastName></person>'
union select '<person><firstName>Bob</firstName><lastName>Burns</lastName></person>'
) tb
SELECT
xmlField.value('(person/firstName)[1]', 'nvarchar(max)') as FirstName
,xmlField.value('(person/lastName)[1]', 'nvarchar(max)') as LastName
FROM tmp
drop table tmp
Run Code Online (Sandbox Code Playgroud)
布里米 这是一个非常有用的发现线程。
我仍然发现其中一些建议令人困惑。每当我在字符串中使用valuewith [1]时,它只会检索第一个值。并建议使用一些建议cross apply(在我的测试中),这些建议会带回太多数据。
因此,这是我的一个简单示例,说明如何创建xml对象,然后将其值读出到表中。
DECLARE @str nvarchar(2000)
SET @str = ''
SET @str = @str + '<users>'
SET @str = @str + ' <user>'
SET @str = @str + ' <firstName>Mike</firstName>'
SET @str = @str + ' <lastName>Gledhill</lastName>'
SET @str = @str + ' <age>31</age>'
SET @str = @str + ' </user>'
SET @str = @str + ' <user>'
SET @str = @str + ' <firstName>Mark</firstName>'
SET @str = @str + ' <lastName>Stevens</lastName>'
SET @str = @str + ' <age>42</age>'
SET @str = @str + ' </user>'
SET @str = @str + ' <user>'
SET @str = @str + ' <firstName>Sarah</firstName>'
SET @str = @str + ' <lastName>Brown</lastName>'
SET @str = @str + ' <age>23</age>'
SET @str = @str + ' </user>'
SET @str = @str + '</users>'
DECLARE @xml xml
SELECT @xml = CAST(CAST(@str AS VARBINARY(MAX)) AS XML)
-- Iterate through each of the "users\user" records in our XML
SELECT
x.Rec.query('./firstName').value('.', 'nvarchar(2000)') AS 'FirstName',
x.Rec.query('./lastName').value('.', 'nvarchar(2000)') AS 'LastName',
x.Rec.query('./age').value('.', 'int') AS 'Age'
FROM @xml.nodes('/users/user') as x(Rec)
Run Code Online (Sandbox Code Playgroud)
这是输出:
这是一种奇怪的语法,但是有一个不错的示例,将它添加到您自己的SQL Server函数中很容易。
说到这里,这是对这个问题的正确答案。
假设您的xml数据@xml的类型xml为变量(如上面的示例所示),这是从问题中引用的xml返回三行数据的方式:
SELECT
x.Rec.query('./firstName').value('.', 'nvarchar(2000)') AS 'FirstName',
x.Rec.query('./lastName').value('.', 'nvarchar(2000)') AS 'LastName'
FROM @xml.nodes('/person') as x(Rec)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
404254 次 |
| 最近记录: |