使用SQL的XML节点

使用SQL的XML节点,sql,sql-server,xml,xquery,shred,Sql,Sql Server,Xml,Xquery,Shred,我有以下XML数据,并希望获得KS中的数据,如下所示: <DW> <KS> <KeyInfo Name="IlluSetting"> <KeyTypeValue>Text</KeyTypeValue> <ValueString>yDipol90</ValueString> </KeyInfo> <KeyInfo Name=

我有以下XML数据,并希望获得KS中的数据,如下所示:

<DW>
  <KS>
    <KeyInfo Name="IlluSetting">
      <KeyTypeValue>Text</KeyTypeValue>
      <ValueString>yDipol90</ValueString>
    </KeyInfo>
     <KeyInfo Name="IlluSetting2">
      <KeyTypeValue>Text</KeyTypeValue>
      <ValueString>yDipol</ValueString>
    </KeyInfo>
  </KS>
  <MDESC>Tx [mrad]</MDESC>
   <MNUMBER>0.12102</MNUMBER>
</DW>
<DW>
  <KS>
    <KeyInfo Name="IlluSetting3">
      <KeyTypeValue>Text</KeyTypeValue>
      <ValueString>yDipol80</ValueString>
    </KeyInfo>
  </KS>
  <MDESC>Ty [mrad]</MDESC>
  <MNUMBER>0.12102</MNUMBER>
</DW>
这意味着里面的数据。。。将显示在一行中


非常感谢

请尝试以下解决方案。我们在这里所做的是所谓的分解,即将XML转换为矩形/关系格式

因为没有提供DDL和样本数据,所以我是从臀部开始拍摄的

由于缺少根元素,提供的XML格式不正确,但SQL Server允许处理XML片段

我们正在使用XQuery及其.nodes和.value方法

SQL,方法1

SQL,方法2


什么是您的数据库及其版本?其sql server 2017 Stabdard版本问问题时,您需要提供一个最小的可复制示例。请参考以下链接:请提供以下内容:1 DDL和示例数据填充,即创建表和插入T-SQL语句。2您需要做什么,即逻辑和代码尝试在T-SQL中实现它。3期望输出,基于上述1中的样本数据。4您的SQL Server版本选择@@version;您好Yitzhak您的答案非常有用,因为我不知道KS中会有多少个KeyInfos,这意味着我们可以在XML中有2个或1个外观,甚至更多,有没有办法动态处理这个问题?@user15427358,我更新了答案。查看它。@user15427358,很高兴听到建议的解决方案对您有效。请投票支持以下建议:
Name            ValueString     Name            ValueString
-----------------------------------------------------------
IlluSetting     yDipol90        IlluSetting2    yDipol
IlluSetting3    yDipol80    
-- DDL and sample data population, start
DECLARE @xml XML =
N'<DW>
    <KS>
        <KeyInfo Name="IlluSetting">
            <KeyTypeValue>Text</KeyTypeValue>
            <ValueString>yDipol90</ValueString>
        </KeyInfo>
        <KeyInfo Name="IlluSetting2">
            <KeyTypeValue>Text</KeyTypeValue>
            <ValueString>yDipol</ValueString>
        </KeyInfo>
    </KS>
    <MDESC>Tx [mrad]</MDESC>
    <MNUMBER>0.12102</MNUMBER>
</DW>
<DW>
    <KS>
        <KeyInfo Name="IlluSetting3">
            <KeyTypeValue>Text</KeyTypeValue>
            <ValueString>yDipol80</ValueString>
        </KeyInfo>
    </KS>
    <MDESC>Ty [mrad]</MDESC>
    <MNUMBER>0.12102</MNUMBER>
</DW>';
-- DDL and sample data population, end

SELECT c.value('KeyInfo[1]/@Name', 'VARCHAR(30)') AS name1
    , c.value('(KeyInfo[1]/ValueString/text())[1]', 'VARCHAR(30)') AS ValueString1
    , COALESCE(c.value('KeyInfo[2]/@Name', 'VARCHAR(30)'), '') AS name2
    , COALESCE(c.value('(KeyInfo[2]/ValueString/text())[1]', 'VARCHAR(30)'), '') AS ValueString2
FROM @xml.nodes('/DW/KS') AS t(c);
+--------------+--------------+--------------+--------------+
|    name1     | ValueString1 |    name2     | ValueString2 |
+--------------+--------------+--------------+--------------+
| IlluSetting  | yDipol90     | IlluSetting2 | yDipol       |
| IlluSetting3 | yDipol80     |              |              |
+--------------+--------------+--------------+--------------+
DECLARE @CrLf CHAR(2) = CHAR(13) + CHAR(10)
   , @tokenCounter INT
   , @i INT = 1;

-- Calculate max number of tokens in the <KS>
SET @tokenCounter = (SELECT MAX(c.value('count(KeyInfo)', 'INT'))
FROM @xml.nodes('/DW/KS') AS t(c));

DECLARE @SQL NVARCHAR(MAX) = 'SELECT ';

WHILE @i <= @tokenCounter BEGIN
    SET @SQL += IIF(@i>1,', ','') + 'COALESCE(c.value(''KeyInfo[' + CAST(@i AS VARCHAR(3)) + ']/@Name'', ''VARCHAR(30)''), '''') AS NAME' + CAST(@i AS VARCHAR(3)) + @CrLf
    SET @SQL += ', COALESCE(c.value(''(KeyInfo[' + CAST(@i AS VARCHAR(3)) + ']/ValueString/text())[1]'', ''VARCHAR(30)''), '''') AS ValueString' + CAST(@i AS VARCHAR(3)) + @CrLf

    SET @i += 1
END

SET @SQL += 'FROM @xml.nodes(''/DW/KS'') AS t(c);';

-- just to see it
PRINT @sql;

-- we are ready at this point
EXEC sp_executesql @stmt = @SQL, @params = N'@xml xml', @xml = @xml;