【问题标题】:Fetching XML attribute of a node element as column and other node element as record value获取节点元素的 XML 属性作为列,其他节点元素作为记录值
【发布时间】:2020-05-08 11:24:32
【问题描述】:

我在 SQL Server 中有一个 XML 列,其中包含如下数据:

<Package>
   <Section name='BOX'>
       <InputNumber description="[1] What is the height of the Box."> 
           <value>25</value>
       </InputNumber>
       <InputNumber description="[2] What is the width of the Box."> 
           <value>30</value>
       </InputNumber>
    </Section>
</Package>

我想得到输出,使得描述中的文本成为列名,值成为它的记录。 输出应该是这样的:

[1] 盒子的高度是多少。 ------ [2] Box的宽度是多少。

25                                        30

我不想将描述作为普通值而是作为列名来获取

【问题讨论】:

  • “我不想将描述作为普通值而是作为列名来获取”——除非描述字符串是固定的,否则没有明智的方法来做到这一点。您需要首先将其作为“正常值”获取,然后使用它来构造动态 SQL,并将值作为列名

标签: sql-server xml tsql xquery


【解决方案1】:

正如@Martin Smith 指出的那样,只有动态 SQL 才能提供帮助。以下是如何实现它。

SQL

-- DDL and sample data population, start
USE tempdb;
GO

DROP TABLE IF EXISTS dbo.tbl;

CREATE TABLE dbo.tbl (ID INT IDENTITY PRIMARY KEY, [Configuration] xml);
INSERT INTO dbo.tbl ([Configuration])
VALUES
(N'<Package>
   <Section name="BOX">
       <InputNumber description="[1] What is the height of the Box."> 
           <value>25</value>
       </InputNumber>
       <InputNumber description="[2] What is the width of the Box."> 
           <value>30</value>
       </InputNumber>
    </Section>
</Package>')
, (N'<Package>
   <Section name="BOX">
       <InputNumber description="[1] What is the height of the Box."> 
           <value>770</value>
       </InputNumber>
       <InputNumber description="[2] What is the width of the Box."> 
           <value>771</value>
       </InputNumber>
    </Section>
</Package>');
-- DDL and sample data population, end

DECLARE @xml XML
    , @colHeader VARCHAR(100)
    , @CrLf CHAR(2) = CHAR(13) + CHAR(10)
    , @SQL AS NVARCHAR(MAX);

SET @xml = (SELECT TOP(1) [Configuration] FROM dbo.tbl);

-- count total number of columns
DECLARE @cnt INT, @i INT;
SET @cnt = @xml.value('count(/Package/Section/InputNumber)', 'INT');

SET @SQL = 'SELECT ID' + @CrLf;

-- loop through XML
SET @i = 1;
WHILE @i <= @cnt BEGIN
   SET @colHeader = @xml.value('(/Package/Section/InputNumber[position() = sql:variable("@i")]/@description)[1]', 'VARCHAR(100)');
   SET @SQL += ', c.value(''(InputNumber[' + CAST(@i AS VARCHAR(5)) + ']/value/text())[1]'', ''NVARCHAR(MAX)'') AS "' + @colHeader + '"' + @CrLf

   SET @i += 1;
END

SET @SQL += 'FROM dbo.tbl as tbl
    CROSS APPLY tbl.[Configuration].nodes(''/Package/Section'') AS t(c);';

PRINT @SQL;
EXEC sys.sp_executesql @SQL;

输出

+----+------------------------------------+-----------------------------------+
| ID | [1] What is the height of the Box. | [2] What is the width of the Box. |
+----+------------------------------------+-----------------------------------+
|  1 |                                 25 |                                30 |
|  2 |                                770 |                               771 |
+----+------------------------------------+-----------------------------------+

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多