串联后防止SQL Server在XML中产生自动关闭标签

时间:2018-12-17 08:44:33

标签: sql sql-server tsql

通过在末尾添加TYPE,可以将自关闭标签从XML中删除。

SELECT N'' as [Col1],
       N'' as [Col2] 
FOR XML PATH('Rows'),TYPE

但是,如果我们想连接两个XML,它将返回

DECLARE @xml1 XML= 
  (SELECT N'' as [Col1],
          N'' as [Col2] 
   FOR XML PATH('Rows'),TYPE);

DECLARE @xml2 XML= 
  (SELECT N'' as [Col1],
          N'' as [Col2] 
   FOR XML PATH('Rows'),TYPE);

select  @xml1,@xml2
FOR XML PATH(''),TYPE

结果是

<Rows>
  <Col1 />
  <Col2 />
</Rows>
<Rows>
  <Col1 />
  <Col2 />
</Rows>

代替

<Rows>
    <Col1></Col1>
    <Col2></Col2>
</Rows>
<Rows>
    <Col1></Col1>
    <Col2></Col2>
</Rows>

有可能吗?

1 个答案:

答案 0 :(得分:0)

  

那为什么TYPE和WITHOUT TYPE的结果不同?

要回答这个问题:它实际上并没有什么不同,因为它在语义上是相同的。

XML不会存储为您看到的标记字符串,而是存储为按层次结构组织的物理表。每当您告诉引擎“向我显示XML!” 时,都会重新创建-仅用于演示。在大多数情况下,引擎将选择最便宜的格式。

我不能真正地看着引擎 ,但我认为

SELECT N'' as [Col1],
       N'' as [Col2] 
FOR XML PATH('Rows'),TYPE

...像这样工作:

  • 好的,我们用<Col1>打开元素Col1。
  • 现在我们输入内容-哦,没有内容
  • 没问题,让我们用</Col1>关闭它
  • 好的,一个新元素。让我们用<Col2>
  • 打开它
  • 等等。

最后的SELECT将返回XML,与创建时一样。

但是此代码

DECLARE @xml1 XML= 
  (SELECT N'' as [Col1],
          N'' as [Col2] 
   FOR XML PATH('Rows'),TYPE);

DECLARE @xml2 XML= 
  (SELECT N'' as [Col1],
          N'' as [Col2] 
   FOR XML PATH('Rows'),TYPE);

...将创建本机类型XML的变量(,TYPE在这里没有任何区别)。变量将以口述的分层格式存储。只需尝试简单的SELECT @xml1。这也会返回带有自动关闭元素的 cheaper 格式。

现在您将它们合并。这意味着,引擎将根据需要 在内部创建XML的内容并创建人类可读的输出(通常称为“ XML”)。

select  @xml1,@xml2
FOR XML PATH(''),TYPE

同样,您也可以在,TYPE之外执行此操作...