如何使用 FOR XML AUTO 子句将特定列 return 作为元素
How to return a specific column as an element with FOR XML AUTO clause
我需要 return 一个特定的列作为 xml 中的一个元素 return 使用 sql 服务器中的 FOR XML AUTO 子句编辑. Automatic return 把所有字段都变成相应元素的属性。好的,但是我需要一个字段或另一个字段作为一个元素。
我有两个表:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Table1](
[Id] [int] NULL,
[Nome] [varchar](50) NULL
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[Table2] Script Date: 02/03/2018 16:24:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Table2](
[Id] [int] NULL,
[DataVencimento] [date] NULL,
[Table1_Id] [int] NULL
) ON [PRIMARY]
GO
INSERT [dbo].[Table1] ([Id], [Nome]) VALUES (1, N'AAA')
GO
INSERT [dbo].[Table1] ([Id], [Nome]) VALUES (2, N'BBB')
GO
INSERT [dbo].[Table1] ([Id], [Nome]) VALUES (3, N'CCC')
GO
INSERT [dbo].[Table2] ([Id], [DataVencimento], [Table1_Id]) VALUES (1, CAST(N'2018-01-01' AS Date), 1)
GO
INSERT [dbo].[Table2] ([Id], [DataVencimento], [Table1_Id]) VALUES (2, CAST(N'2018-01-02' AS Date), 2)
GO
INSERT [dbo].[Table2] ([Id], [DataVencimento], [Table1_Id]) VALUES (3, CAST(N'2018-01-03' AS Date), 2)
GO
我认为他们之间有如下关系:
select
Table1.Id,
Table1.Nome,
Table2.Id,
Table2.DataVencimento
from Table1
inner join Table2 on Table2.Table1_Id = Table1.Id
order by Table1.Id, Table2.Id
for xml auto, root('ArrayOfTable1')
其中 return 个:
<ArrayOfTable1>
<Table1 Id="1" Nome="AAA">
<Table2 Id="1" DataVencimento="2018-01-01" />
</Table1>
<Table1 Id="2" Nome="BBB">
<Table2 Id="2" DataVencimento="2018-01-02" />
<Table2 Id="3" DataVencimento="2018-01-03" />
</Table1>
</ArrayOfTable1>
但是我需要 DataVencimento 作为一个元素,像这样:
<ArrayOfTable1>
<Table1 Id="1" Nome="AAA">
<Table2 Id="1">
<DataVencimento>2018-01-01</DataVencimento>
</Table2>
</Table1>
<Table1 Id="2" Nome="BBB">
<Table2 Id="2">
<DataVencimento>2018-01-02</DataVencimento>
</Table2>
<Table2 Id="3">
<DataVencimento>2018-01-03</DataVencimento>
</Table2>
</Table1>
</ArrayOfTable1>
如何操作?
我现在不知道是否有更清洁的解决方案,但像这样的方法应该可行:
select
Table1.Id as [@Id],
Table1.Nome as [@Nome],
[inner].[xml] as [*]
from Table1
outer apply
( select (select
Table2.Id as [@Id],
Table2.DataVencimento
from Table2
where Table2.Table1_Id = Table1.Id
for xml path('Table2'), type) as [xml]
) as [inner]
inner join Table2 on Table2.Table1_Id = Table1.Id
order by Table1.Id, Table2.Id
for xml path('Table1'), root('ArrayOfTable1')
select
Table1.ID,
Table1.Nome,
Table2.Id,
(select table2.DataVencimento for xml path(''), elements, type)
from Table1
inner join Table2 on Table2.Table1_Id = Table1.Id
order by Table1.Id, Table2.Id
for xml auto, root('ArrayOfTable1')
输出:
<ArrayOfTable1>
<Table1 ID="1" Nome="AAA">
<Table2 Id="1">
<DataVencimento>2018-01-01</DataVencimento>
</Table2>
</Table1>
<Table1 ID="2" Nome="BBB">
<Table2 Id="2">
<DataVencimento>2018-01-02</DataVencimento>
</Table2>
<Table2 Id="3">
<DataVencimento>2018-01-03</DataVencimento>
</Table2>
</Table1>
</ArrayOfTable1>
在大多数情况下,FOR XML PATH()
是首选方法。使用 PATH
您可以完全控制输出。没有什么是自动...
试试看:
SELECT t1.Id AS [@id]
,t1.Nome AS [@Nome]
,(
SELECT t2.Id AS [@Id]
,t2.DataVencimento
FROM dbo.Table2 AS t2
WHERE t1.Id=t2.Table1_Id
ORDER BY t2.Id
FOR XML PATH('Table2'),TYPE
)
FROM dbo.Table1 AS t1
WHERE EXISTS(SELECT 1 FROM dbo.Table2 WHERE Table2.Table1_Id=t1.Id)
ORDER BY t1.Id
FOR XML PATH('Table1'), ROOT('ArrayOfTable1');
我需要 return 一个特定的列作为 xml 中的一个元素 return 使用 sql 服务器中的 FOR XML AUTO 子句编辑. Automatic return 把所有字段都变成相应元素的属性。好的,但是我需要一个字段或另一个字段作为一个元素。
我有两个表:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Table1](
[Id] [int] NULL,
[Nome] [varchar](50) NULL
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[Table2] Script Date: 02/03/2018 16:24:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Table2](
[Id] [int] NULL,
[DataVencimento] [date] NULL,
[Table1_Id] [int] NULL
) ON [PRIMARY]
GO
INSERT [dbo].[Table1] ([Id], [Nome]) VALUES (1, N'AAA')
GO
INSERT [dbo].[Table1] ([Id], [Nome]) VALUES (2, N'BBB')
GO
INSERT [dbo].[Table1] ([Id], [Nome]) VALUES (3, N'CCC')
GO
INSERT [dbo].[Table2] ([Id], [DataVencimento], [Table1_Id]) VALUES (1, CAST(N'2018-01-01' AS Date), 1)
GO
INSERT [dbo].[Table2] ([Id], [DataVencimento], [Table1_Id]) VALUES (2, CAST(N'2018-01-02' AS Date), 2)
GO
INSERT [dbo].[Table2] ([Id], [DataVencimento], [Table1_Id]) VALUES (3, CAST(N'2018-01-03' AS Date), 2)
GO
我认为他们之间有如下关系:
select
Table1.Id,
Table1.Nome,
Table2.Id,
Table2.DataVencimento
from Table1
inner join Table2 on Table2.Table1_Id = Table1.Id
order by Table1.Id, Table2.Id
for xml auto, root('ArrayOfTable1')
其中 return 个:
<ArrayOfTable1>
<Table1 Id="1" Nome="AAA">
<Table2 Id="1" DataVencimento="2018-01-01" />
</Table1>
<Table1 Id="2" Nome="BBB">
<Table2 Id="2" DataVencimento="2018-01-02" />
<Table2 Id="3" DataVencimento="2018-01-03" />
</Table1>
</ArrayOfTable1>
但是我需要 DataVencimento 作为一个元素,像这样:
<ArrayOfTable1>
<Table1 Id="1" Nome="AAA">
<Table2 Id="1">
<DataVencimento>2018-01-01</DataVencimento>
</Table2>
</Table1>
<Table1 Id="2" Nome="BBB">
<Table2 Id="2">
<DataVencimento>2018-01-02</DataVencimento>
</Table2>
<Table2 Id="3">
<DataVencimento>2018-01-03</DataVencimento>
</Table2>
</Table1>
</ArrayOfTable1>
如何操作?
我现在不知道是否有更清洁的解决方案,但像这样的方法应该可行:
select
Table1.Id as [@Id],
Table1.Nome as [@Nome],
[inner].[xml] as [*]
from Table1
outer apply
( select (select
Table2.Id as [@Id],
Table2.DataVencimento
from Table2
where Table2.Table1_Id = Table1.Id
for xml path('Table2'), type) as [xml]
) as [inner]
inner join Table2 on Table2.Table1_Id = Table1.Id
order by Table1.Id, Table2.Id
for xml path('Table1'), root('ArrayOfTable1')
select
Table1.ID,
Table1.Nome,
Table2.Id,
(select table2.DataVencimento for xml path(''), elements, type)
from Table1
inner join Table2 on Table2.Table1_Id = Table1.Id
order by Table1.Id, Table2.Id
for xml auto, root('ArrayOfTable1')
输出:
<ArrayOfTable1>
<Table1 ID="1" Nome="AAA">
<Table2 Id="1">
<DataVencimento>2018-01-01</DataVencimento>
</Table2>
</Table1>
<Table1 ID="2" Nome="BBB">
<Table2 Id="2">
<DataVencimento>2018-01-02</DataVencimento>
</Table2>
<Table2 Id="3">
<DataVencimento>2018-01-03</DataVencimento>
</Table2>
</Table1>
</ArrayOfTable1>
在大多数情况下,FOR XML PATH()
是首选方法。使用 PATH
您可以完全控制输出。没有什么是自动...
试试看:
SELECT t1.Id AS [@id]
,t1.Nome AS [@Nome]
,(
SELECT t2.Id AS [@Id]
,t2.DataVencimento
FROM dbo.Table2 AS t2
WHERE t1.Id=t2.Table1_Id
ORDER BY t2.Id
FOR XML PATH('Table2'),TYPE
)
FROM dbo.Table1 AS t1
WHERE EXISTS(SELECT 1 FROM dbo.Table2 WHERE Table2.Table1_Id=t1.Id)
ORDER BY t1.Id
FOR XML PATH('Table1'), ROOT('ArrayOfTable1');