以XML格式检索SQL数据时出现问题

时间:2019-09-03 20:45:18

标签: sql sql-server xml

我遇到了一个SQL查询问题,该查询旨在将生成的数据作为XML返回。这是一个代码转储,向您显示所有发生的事情:

SQL查询(注意:已删除表名和列名)

with resultdata as
(
    SELECT 
    (
        select * from Table1 (nolock)
        where column1 = 99999 and column2 = -1 for xml auto, type
    ) as tabledata 
    UNION ALL
    SELECT
    (   
        select * from Table2 (nolock)
        where column1 = 99999 and column2 = -1 for xml auto, type 
    )
    UNION ALL
    SELECT
    (
        select * from Table3 (nolock)
        where column1 = 99999 and column2 = -1 for xml auto, type
    )
    UNION ALL
    SELECT 
    (
        select * from Table4 (nolock)
        where column1 = 99999 and column2 = -1 for xml auto, type
    )
    UNION ALL
    SELECT 
    (
        select * from Table5 (nolock)
        where column1 = 99999 and column2 = -1 for xml auto, type
    )
    UNION ALL
    SELECT 
    (
        select * from Table6 (nolock)
        where column1 = 99999 and column2 = -1 for xml auto, type
    )
    UNION ALL
    SELECT 
    (
        select * from Table7 (nolock)
        where column1 = 99999 and column2 = -1 for xml auto, type
    )
    UNION ALL
    SELECT 
    (
        select * from Table8 (nolock)
        where column1 = 99999 and column2 = -1 for xml auto, type
    )
)

select * from resultdata result for xml auto, elements

这将返回一个类似于以下内容的XML结果(大部分XML已删除,注释是实际数据所在的位置):

<result>
  <tabledata>
    <!--Table1 results-->
  </tabledata>
</result>
<result>
  <tabledata>
    <!--Table2 results-->
  </tabledata>
</result>
<result>
  <tabledata>
    <!--Table3 results-->
  </tabledata>
</result>
<result>
  <tabledata>
    <!--Table4 results-->
  </tabledata>
</result>
<result>
  <tabledata>
    <!--Table5 results-->
  </tabledata>
</result>
<result>
  <tabledata>
    <!--Table6 results-->
  </tabledata>
</result>
<result>
  <tabledata>
   <!--Table7 results-->
  </tabledata>
</result>
<result>
  <tabledata>
    <!--Table8 results-->
  </tabledata>
</result>

很明显,这是格​​式错误的XML,但我似乎无法对其进行重新处理,以便它以正确的格式为我提供结果,如下所示:

<result>
  <tabledata>
    <!--Table1 results-->
  </tabledata>
  <tabledata>
    <!--Table2 results-->
  </tabledata>
  <tabledata>
    <!--Table3 results-->
  </tabledata>
  <tabledata>
    <!--Table4 results-->
  </tabledata>
  <tabledata>
    <!--Table5 results-->
  </tabledata>
  <tabledata>
    <!--Table6 results-->
  </tabledata>
  <tabledata>
   <!--Table7 results-->
  </tabledata>
  <tabledata>
    <!--Table8 results-->
  </tabledata>
</result>

作为旁注,这是对我们现有查询的重写,这就是为什么语法主要是这样的原因。我的一个同事开始对其进行重新加工,并从本质上给了我我在这里发布的内容,但是我一直在努力尝试使用他的更改使它起作用。如果我需要将其报废并从头开始,那么这样做没有问题。

此外,还要注意一点,我希望它看起来像的XML必须是这种方式,因为它最终会由我无法控制的XSLT使用。此查询的旧版本以不同的列名称返回每个tabledata元素,然后在调用它的C#代码中替换了字符串。对于在此XML上进行多个字符串替换(可能超过100k行),存在性能问题,因此答案是更改查询以按照我们需要的方式返回数据。

4 个答案:

答案 0 :(得分:2)

另一个选择。这将返回您想要的结果。

Select (select * from Table1 (nolock) where column1 = 99999 and column2 = -1 for XML auto, type, root('tabledata') )
      ,(Select * from Table2 (nolock) where column1 = 99999 and column2 = -1 for XML auto, type, root('tabledata') )
      ,(Select * from Table3 (nolock) where column1 = 99999 and column2 = -1 for XML auto, type, root('tabledata') )
 For XML Path(''),Root('results')

答案 1 :(得分:1)

在SQL Server中,XML变量,列或FOR XML查询结果表示“ XML片段”,而没有单个顶级元素。

如果需要XML文档(带有顶级根元素),则FOR XML查询可为FOR XML添加ROOT参数。

答案 2 :(得分:1)

如果我正确理解了您的问题,则应将每个表的查询合并在一起,然后应用XML格式。这样...

WITH resultdata AS
(
    SELECT (
               SELECT *
               FROM   (
                          SELECT *
                          FROM   Table1 (NOLOCK)
                          WHERE  column1 = 99999
                                 AND column2 = -1
                          UNION ALL
                          SELECT *
                          FROM   Table2 (NOLOCK)
                          WHERE  column1 = 99999
                                 AND column2 = -1
                          UNION ALL
                          SELECT *
                          FROM   Table3 (NOLOCK)
                          WHERE  column1 = 99999
                                 AND column2 = -1
                          UNION ALL
                          SELECT *
                          FROM   Table4 (NOLOCK)
                          WHERE  column1 = 99999
                                 AND column2 = -1
                          UNION ALL
                          SELECT *
                          FROM   Table5 (NOLOCK)
                          WHERE  column1 = 99999
                                 AND column2 = -1
                          UNION ALL
                          SELECT *
                          FROM   Table6 (NOLOCK)
                          WHERE  column1 = 99999
                                 AND column2 = -1
                          UNION ALL
                          SELECT *
                          FROM   Table7 (NOLOCK)
                          WHERE  column1 = 99999
                                 AND column2 = -1
                          UNION ALL
                          SELECT *
                          FROM   Table8 (NOLOCK)
                          WHERE  column1 = 99999
                                 AND column2 = -1
                      ) AS x
               FOR XML AUTO, TYPE
           ) AS tabledata
)
SELECT * FROM resultdata AS result FOR XML AUTO, ELEMENTS;

答案 3 :(得分:0)

下面的解决方案如何允许从具有不同结构的DB表的根构造最终XML。

  

SQL

-- DDL and sample data population, start
DECLARE @tbl1 TABLE (ID INT IDENTITY(1,1) PRIMARY KEY, city VARCHAR(30));
INSERT INTO @tbl1
VALUES
('Miami')
, ('Orlando');

DECLARE @tbl2 TABLE (ID INT IDENTITY(1,1) PRIMARY KEY, [state] VARCHAR(30));
INSERT INTO @tbl2
VALUES
('Florida')
, ('Texas');
-- DDL and sample data population, end

WITH resultdata (tabledata) AS
(
    SELECT 
    (
        SELECT * FROM @tbl1
        FOR XML PATH('row'), TYPE, ROOT('tbl1')
    ) AS [tbl1]
    UNION ALL
    SELECT
    (   
        SELECT * FROM @tbl2
        FOR XML PATH('row'), TYPE, ROOT('tbl2')
    )
)
SELECT * 
FROM resultdata
FOR XML PATH(''), TYPE, ROOT('result');
  

输出XML

<result>
  <tabledata>
    <tbl1>
      <row>
        <ID>1</ID>
        <city>Miami</city>
      </row>
      <row>
        <ID>2</ID>
        <city>Orlando</city>
      </row>
    </tbl1>
  </tabledata>
  <tabledata>
    <tbl2>
      <row>
        <ID>1</ID>
        <state>Florida</state>
      </row>
      <row>
        <ID>2</ID>
        <state>Texas</state>
      </row>
    </tbl2>
  </tabledata>
</result>