创建 XML 文件时在 SQL 中联合
Posted
技术标签:
【中文标题】创建 XML 文件时在 SQL 中联合【英文标题】:Union in SQL while creating XML file 【发布时间】:2016-05-25 07:18:25 【问题描述】:我在创建 XML 文件的 SQL 查询时遇到了一些问题。我想做UNION
这个查询,但它不起作用。
(SELECT 1 AS "ns0:kindOfItem",
code AS "ns0:wholeCode",
REPLACE(weight, ',', '.') AS "ns0:weight",
1 AS "ns0:ammountOfNumbers",
(SELECT price AS "ns0:value",
'EUR' as "ns0:currency"
FOR XML PATH ('ns0:sendedItems'), TYPE),
(SELECT
'EUR' as "ns0:currency"
FOR XML PATH ('ns0:present'), TYPE)
FROM [PL].[dbo].[dk_documents] where id in (1,2,3)
FOR XML PATH('test'))
这个查询工作正常,但是当我尝试像这里一样做UNION
时:
(SELECT 1 AS "ns0:kindOfItem",
code AS "ns0:wholeCode",
REPLACE(weight, ',', '.') AS "ns0:weight",
1 AS "ns0:ammountOfNumbers",
(SELECT price AS "ns0:value",
'EUR' as "ns0:currency"
FOR XML PATH ('ns0:sendedItems'), TYPE),
(SELECT
'EUR' as "ns0:currency"
FOR XML PATH ('ns0:present'), TYPE)
FROM [PL].[dbo].[dk_documents] where id in (1,2,3)
UNION
(SELECT 1 AS "ns0:kindOfItem",
code AS "ns0:wholeCode",
REPLACE(weight, ',', '.') AS "ns0:weight",
1 AS "ns0:ammountOfNumbers",
(SELECT price AS "ns0:value",
'EUR' as "ns0:currency"
FOR XML PATH ('ns0:sendedItems'), TYPE),
(SELECT
'EUR' as "ns0:currency"
FOR XML PATH ('ns0:present'), TYPE)
FROM [PL2].[dbo].[dk_documents] where id in (1,2,3)
FOR XML PATH('test'))
这个查询给我一个错误:
数据类型 xml 不能用作 UNION、INTERSECT 的操作数 或 EXCEPT 运算符,因为它不可比较。
【问题讨论】:
错误信息很清楚,您的选择至少有一列的数据类型不兼容。 (第 1 列必须一直兼容,第 2、第 3 等也是如此。) 我有点知道 :) 但我不知道如何解决它,当我在没有“FOR XML PATH ('ns0:sendedItems'), TYPE)”和“FOR XML”的情况下执行此查询时PATH ('ns0:present'), TYPE)" 它可以正常工作,但是 xml 架构不正常。 我不确定我是否完全理解您要做什么,但可能先union
数据,然后从中生成 xml,而不是合并两个 xml。
是的,但我不知道该怎么做。
【参考方案1】:
使用UNION
将删除结果的重复值,因此 SQL Server 必须将第一部分的 XML 与第二部分的 XML 进行比较,并确定它们是否相等且未针对 XML 实现。
您可能不希望重复检查,因此改为UNION ALL
,它也适用于 XML 数据。
【讨论】:
谢谢队友 :) 我把它改成 UNION ALL 并且它工作正常【参考方案2】:您可能对此感兴趣:
请比较以下
“测试”一词出现在两个列表中。 UNION
会隐式执行 DISTINCT
,因此“测试”只出现一次。
SELECT *
FROM (VALUES('this'),('is'),('a'),('test')) AS tbl(Words)
UNION
SELECT *
FROM (VALUES('and'),('another'),('test')) AS tbl(Words);
和UNION ALL
一样会让“测试”出现两次
SELECT *
FROM (VALUES('this'),('is'),('a'),('test')) AS tbl(Words)
UNION ALL
SELECT *
FROM (VALUES('and'),('another'),('test')) AS tbl(Words);
您可以将UNION SELECT
放入周围的SELECT
(UNION
或UNION ALL
并为整个结果集设置FOR XML PATH
命名空间是重复创建的,没有错,但很烦人(参见:https://***.com/a/35648751/5089204 和链接的 Connect-Article)
WITH XMLNAMESPACES(DEFAULT 'Dummy')
SELECT *
FROM
(
SELECT *
FROM (VALUES('this'),('is'),('a'),('test')) AS tbl(Words)
UNION
SELECT *
FROM (VALUES('and'),('another'),('test')) AS tbl(Words)
) AS MetaTable
FOR XML Path(''),ROOT('UNION_TEST');
这将带回两个列表,每个列表都有自己的 XML 标记,还有重复的命名空间(见前文)
WITH XMLNAMESPACES(DEFAULT 'Dummy')
SELECT
(
SELECT *
FROM (VALUES('this'),('is'),('a'),('test')) AS tbl(Words)
FOR XML PATH(''),ROOT('FirstBlock'),TYPE
)
,(
SELECT *
FROM (VALUES('and'),('another'),('test')) AS tbl(Words)
FOR XML PATH(''),ROOT('FirstBlock'),TYPE
)
FOR XML Path(''),ROOT('UNION_TEST');
最后你也可以使用它(ALL
或不使用):
WITH XMLNAMESPACES(DEFAULT 'Dummy')
SELECT *
FROM (VALUES('this'),('is'),('a'),('test')) AS tbl(Words)
UNION ALL
SELECT *
FROM (VALUES('and'),('another'),('test')) AS tbl(Words)
FOR XML PATH(''),ROOT('UNION_TEST');
【讨论】:
以上是关于创建 XML 文件时在 SQL 中联合的主要内容,如果未能解决你的问题,请参考以下文章