XML SQL Server查询以检索属性值和标记文本值

XML SQL Server查询以检索属性值和标记文本值,sql,sql-server,xml,Sql,Sql Server,Xml,我不熟悉在SQL Server中查询XML,这不是我的日常任务之一,我正在帮助一位同事。例如,我将以下XML存储在SQL中的一列中: 如何检索两列,一列具有id值,另一列具有来自下一个内部标记的值,例如:2109和0 期望输出: id value 2109 0 341 2 342 10 2196 753064REPJ1 1283 2 1293 0_Imprumutat 谢谢 您需要使用XQuery、外部应用和指定目标节点的路径 最终查询 说明: 导航到

我不熟悉在SQL Server中查询XML,这不是我的日常任务之一,我正在帮助一位同事。例如,我将以下XML存储在SQL中的一列中:

如何检索两列,一列具有id值,另一列具有来自下一个内部标记的值,例如:2109和0

期望输出:

id  value
2109    0
341     2
342     10
2196    753064REPJ1
1283    2
1293    0_Imprumutat
谢谢

您需要使用XQuery、外部应用和指定目标节点的路径

最终查询

说明:

导航到所需节点后,使用n.a.value“@Attribute”、“datatype”语法获取所需属性,使用n.a.value“ElementName[1]”、“datatype”语法获取元素值。

您可以在XPATH表达式中使用sql:variable或sql:column。我声明了一个XML变量@x,并将其设置为上面给出的XML

有了这个,你就可以得到你想要的:

DECLARE @outerID INT=645;
DECLARE @innerID INT=2109;

SELECT @x.value('(/Item[@id=sql:variable("@outerID")]/Row[1]/Item[@id=sql:variable("@innerID")]/Bool)[1]','bit')
如果XML中的所有行节点都需要它,可以这样做:

DECLARE @id INT=2109;
SELECT Item.OneRow.value('(*[@id=sql:variable("@id")])[1]','bit')
FROM @x.nodes('/Item/Row') AS Item(OneRow)
此语句将提取所有ID、第一个子项的名称和值以及其他行号:

;WITH TheRows AS
(
    SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowInx
          ,AllRows.OneRow.query('.') AS RowXML
    FROM @x.nodes('/Item/Row') AS AllRows(OneRow) 
)
SELECT RowInx
      ,AllRowItems.OneItem.value('@id','int') AS id
      ,AllRowItems.OneItem.value('@flags','int') AS flags
      ,AllRowItems.OneItem.query('fn:local-name(./*[1])') AS elementName
      ,AllRowItems.OneItem.value('(./*)[1]','varchar(max)') AS elementValue
FROM TheRows
CROSS APPLY RowXML.nodes('/Row/Item') AS AllRowItems(OneItem)

您是否希望其项目Id始终为0?如果您在此处发布一些您想要的示例输出,那将非常好
DECLARE @id INT=2109;
SELECT Item.OneRow.value('(*[@id=sql:variable("@id")])[1]','bit')
FROM @x.nodes('/Item/Row') AS Item(OneRow)
;WITH TheRows AS
(
    SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowInx
          ,AllRows.OneRow.query('.') AS RowXML
    FROM @x.nodes('/Item/Row') AS AllRows(OneRow) 
)
SELECT RowInx
      ,AllRowItems.OneItem.value('@id','int') AS id
      ,AllRowItems.OneItem.value('@flags','int') AS flags
      ,AllRowItems.OneItem.query('fn:local-name(./*[1])') AS elementName
      ,AllRowItems.OneItem.value('(./*)[1]','varchar(max)') AS elementValue
FROM TheRows
CROSS APPLY RowXML.nodes('/Row/Item') AS AllRowItems(OneItem)