我们正在将SQL Server 2008 R2升级到SQL Server 2012(我知道,我们很少有版本,但这是一个暂时的解决方案)来利用2008年没有的一些功能。在此过程中,我们确定了当UNION语句存在时SQL Server 2012如何处理XML Auto的问题/差异。
这是我想要实现的格式:
<Product Color="Black" EnglishProductName="Full-Finger Gloves, L" Customizable="0">
<ProductSubCategory EnglishProductSubcategoryName="Gloves" FrenchProductSubcategoryName="Gants" />
</Product>
<Product Color="Black" EnglishProductName="Full-Finger Gloves, M" Customizable="0">
<ProductSubCategory EnglishProductSubcategoryName="Gloves" FrenchProductSubcategoryName="Gants" />
</Product>
<Product Color="Black" EnglishProductName="Full-Finger Gloves, S" Customizable="0">
<ProductSubCategory EnglishProductSubcategoryName="Gloves" FrenchProductSubcategoryName="Gants" />
</Product>
<Product Color="Black" EnglishProductName="Half-Finger Gloves, L" Customizable="0">
<ProductSubCategory EnglishProductSubcategoryName="Gloves" FrenchProductSubcategoryName="Gants" />
</Product>
<Product Color="Black" EnglishProductName="Half-Finger Gloves, M" Customizable="0">
<ProductSubCategory EnglishProductSubcategoryName="Gloves" FrenchProductSubcategoryName="Gants" />
</Product>
<Product Color="Black" EnglishProductName="Half-Finger Gloves, S" Customizable="0">
<ProductSubCategory EnglishProductSubcategoryName="Gloves" FrenchProductSubcategoryName="Gants" />
</Product>
以下是产生上述代码的代码(使用AdventureWorksDB):
Select Distinct Product.Color, Product.EnglishProductName, 0 as Customizable,
ProductSubCategory.EnglishProductSubcategoryName,
ProductSubCategory.FrenchProductSubcategoryName
From dbo.DimProduct as Product
Inner Join dbo.DimProductSubcategory As ProductSubCategory On ProductSubCategory.ProductSubcategoryKey = Product.ProductSubcategoryKey
For Xml Auto
但是当我添加UNION语句时,它会中断我的XML输出:
<Product Color="Black" EnglishProductName="Full-Finger Gloves, L" Customizable="0" EnglishProductSubcategoryName="Gloves" FrenchProductSubcategoryName="Gants" />
<Product Color="Black" EnglishProductName="Full-Finger Gloves, L" Customizable="1" EnglishProductSubcategoryName="Gloves" FrenchProductSubcategoryName="Gants" />
<Product Color="Black" EnglishProductName="Full-Finger Gloves, M" Customizable="0" EnglishProductSubcategoryName="Gloves" FrenchProductSubcategoryName="Gants" />
<Product Color="Black" EnglishProductName="Full-Finger Gloves, M" Customizable="1" EnglishProductSubcategoryName="Gloves" FrenchProductSubcategoryName="Gants" />
<Product Color="Black" EnglishProductName="Full-Finger Gloves, S" Customizable="0" EnglishProductSubcategoryName="Gloves" FrenchProductSubcategoryName="Gants" />
<Product Color="Black" EnglishProductName="Full-Finger Gloves, S" Customizable="1" EnglishProductSubcategoryName="Gloves" FrenchProductSubcategoryName="Gants" />
<Product Color="Black" EnglishProductName="Half-Finger Gloves, L" Customizable="0" EnglishProductSubcategoryName="Gloves" FrenchProductSubcategoryName="Gants" />
<Product Color="Black" EnglishProductName="Half-Finger Gloves, L" Customizable="1" EnglishProductSubcategoryName="Gloves" FrenchProductSubcategoryName="Gants" />
<Product Color="Black" EnglishProductName="Half-Finger Gloves, M" Customizable="0" EnglishProductSubcategoryName="Gloves" FrenchProductSubcategoryName="Gants" />
<Product Color="Black" EnglishProductName="Half-Finger Gloves, M" Customizable="1" EnglishProductSubcategoryName="Gloves" FrenchProductSubcategoryName="Gants" />
<Product Color="Black" EnglishProductName="Half-Finger Gloves, S" Customizable="0" EnglishProductSubcategoryName="Gloves" FrenchProductSubcategoryName="Gants" />
<Product Color="Black" EnglishProductName="Half-Finger Gloves, S" Customizable="1" EnglishProductSubcategoryName="Gloves" FrenchProductSubcategoryName="Gants" />
以下是产生上述代码的代码:
Select Distinct Product.Color, Product.EnglishProductName, 0 as Customizable,
ProductSubCategory.EnglishProductSubcategoryName,
ProductSubCategory.FrenchProductSubcategoryName
From dbo.DimProduct as Product
Inner Join dbo.DimProductSubcategory As ProductSubCategory On ProductSubCategory.ProductSubcategoryKey = Product.ProductSubcategoryKey
Union
Select Distinct Product.Color, Product.EnglishProductName, 1 as Customizable,
ProductSubCategory.EnglishProductSubcategoryName,
ProductSubCategory.FrenchProductSubcategoryName
From dbo.DimProduct as Product
Inner Join dbo.DimProductSubcategory As ProductSubCategory On ProductSubCategory.ProductSubcategoryKey = Product.ProductSubcategoryKey
For Xml Auto
我需要ProductSubCategory在XML输出中保留Product节点的子节点,即使使用UNION语句也是如此。 UNION对2008年的XML输出没有影响,但出于某种原因,SQL Server 2012以不同的方式处理相同的语句。任何帮助表示赞赏。希望我足够清楚。谢谢。
下次请提供一些耗材格式的样本数据,最好是DDL,INSERT和您的工作代码作为独立的MCVE。这有很大帮助。这次我为你打字:
一些包含数据的模型表:
DECLARE @Product TABLE(ProductKey INT IDENTITY,Color VARCHAR(100),EnglishProductName VARCHAR(100),ProductSubcategoryKey INT);
INSERT INTO @Product VALUES('Black','Full-Finger Gloves, L',1)
,('Black','Full-Finger Gloves, M',1)
,('Black','Full-Finger Gloves, S',1)
,('Black','Half-Finger Gloves, L',1)
,('Black','Half-Finger Gloves, M',1)
,('Black','Half-Finger Gloves, S',1);
DECLARE @ProductSubCategory TABLE(ProductSubcategoryKey INT IDENTITY,EnglishProductSubcategoryName VARCHAR(100));
INSERT INTO @ProductSubCategory VALUES('Gloves');
- 查询使用FOR XML PATH
而不是AUTO
模式。我稍后会解释
Select Distinct Product.Color AS [@Color]
, Product.EnglishProductName AS [@EnglishProductName]
, 0 as [@Customizable]
, ProductSubCategory.EnglishProductSubcategoryName AS [ProductSubCategory/@EnglishProductSubcategoryName]
From @Product as Product
Inner Join @ProductSubCategory As ProductSubCategory On ProductSubCategory.ProductSubcategoryKey = Product.ProductSubcategoryKey
UNION
Select Distinct Product.Color AS [@Color]
, Product.EnglishProductName AS [@EnglishProductName]
, 1 as [@Customizable]
, ProductSubCategory.EnglishProductSubcategoryName AS [ProductSubCategory/@EnglishProductSubcategoryName]
From @Product as Product
Inner Join @ProductSubCategory As ProductSubCategory On ProductSubCategory.ProductSubcategoryKey = Product.ProductSubcategoryKey
For Xml PATH('Product');
一些解释:
您使用AUTO
的方法允许引擎决定您将获得什么。总的来说,我不喜欢这样的想法。内部实施的任何改变都会炸毁生产中的系统。更好地使用PATH
,它可以让你对你得到的东西有最深的控制。
不需要工会
如果我正确地得到了这个,你使用UNION
只是为了将每个产品添加两次。一行在@Customizable
处为零,第二行为1.一个简单的CROSS JOIN
与VALUES
设置将做同样的,但更快更好阅读:
Select Distinct Product.Color AS [@Color]
, Product.EnglishProductName AS [@EnglishProductName]
, A.Customizable as [@Customizable]
, ProductSubCategory.EnglishProductSubcategoryName AS [ProductSubCategory/@EnglishProductSubcategoryName]
From @Product as Product
Inner Join @ProductSubCategory As ProductSubCategory On ProductSubCategory.ProductSubcategoryKey = Product.ProductSubcategoryKey
CROSS JOIN (VALUES(1),(0)) A(Customizable)
For Xml PATH('Product')
可读性
使用表别名很好,但我建议使用像这里更短的别名
Select Distinct p.Color AS [@Color]
, p.EnglishProductName AS [@EnglishProductName]
, A.Customizable as [@Customizable]
, sc.EnglishProductSubcategoryName AS [ProductSubCategory/@EnglishProductSubcategoryName]
From @Product as p
Inner Join @ProductSubCategory As sc On sc.ProductSubcategoryKey = p.ProductSubcategoryKey
CROSS JOIN (VALUES(1),(0)) A(Customizable)
For Xml PATH('Product');
结构体
迟早你将拥有一个属于多个SubCategory的产品。我建议将其设计为n:m
相关系统,其间有映射表
最终的XML
因为您的SubCategory更类似于产品系列您可能会创建类似的东西
<ProductSubCategory EnglishProductSubcategoryName="Gloves">
<Product Color="Black" EnglishProductName="Full-Finger Gloves, L" Customizable="0" />
<Product Color="Black" EnglishProductName="Full-Finger Gloves, L" Customizable="1" />
<Product Color="Black" EnglishProductName="Full-Finger Gloves, M" Customizable="0" />
<Product Color="Black" EnglishProductName="Full-Finger Gloves, M" Customizable="1" />
<Product Color="Black" EnglishProductName="Full-Finger Gloves, S" Customizable="0" />
<Product Color="Black" EnglishProductName="Full-Finger Gloves, S" Customizable="1" />
<Product Color="Black" EnglishProductName="Half-Finger Gloves, L" Customizable="0" />
<Product Color="Black" EnglishProductName="Half-Finger Gloves, L" Customizable="1" />
<Product Color="Black" EnglishProductName="Half-Finger Gloves, M" Customizable="0" />
<Product Color="Black" EnglishProductName="Half-Finger Gloves, M" Customizable="1" />
<Product Color="Black" EnglishProductName="Half-Finger Gloves, S" Customizable="0" />
<Product Color="Black" EnglishProductName="Half-Finger Gloves, S" Customizable="1" />
<ProductSubCategory>
甚至更简单
<ProductSubCategory EnglishProductSubcategoryName="Gloves">
<Customizable value=1>
<Product Color="Black" EnglishProductName="Full-Finger Gloves, L" />
<Product Color="Black" EnglishProductName="Full-Finger Gloves, M" />
<Product Color="Black" EnglishProductName="Full-Finger Gloves, S" />
<Product Color="Black" EnglishProductName="Half-Finger Gloves, L" />
<Product Color="Black" EnglishProductName="Half-Finger Gloves, M" />
<Product Color="Black" EnglishProductName="Half-Finger Gloves, S" />
</Customizable>
<Customizable value=0>
<Product Color="Black" EnglishProductName="Full-Finger Gloves, L" />
<Product Color="Black" EnglishProductName="Full-Finger Gloves, M" />
<Product Color="Black" EnglishProductName="Full-Finger Gloves, S" />
<Product Color="Black" EnglishProductName="Half-Finger Gloves, L" />
<Product Color="Black" EnglishProductName="Half-Finger Gloves, M" />
<Product Color="Black" EnglishProductName="Half-Finger Gloves, S" />
</Customizable>
<ProductSubCategory>