我正在尝试使用Sql Server 2012 Express在表中创建一些XML值。具体来说,我希望一个元素具有来自1个表的属性,并且该元素具有来自另一个表的值。用例是属性表示内部Id,而值/文本表示人类可读的内容。
我有两张桌子:
卡,其中包含列
Id, Name, BookId, and Page
类别,其中包含列
Id and Name
所需的XML是:
<Card id="2">
<Name>My Card</Name>
<Location>
<Book cid="66">My Book</Book>
<Page>118</Page>
</Location>
</Card>
注意“Book”元素,它具有Card表中的属性和Category表中的Value / Text。
我已经尝试了两个让我非常接近的查询,但并不完全相同。这个查询会将book id放在“Location”元素中(boo!),但它按照我想要的方式构造元素(是的!):
select
c.Id [@id],
c.Name,
(
select
(
select
c.BookId [@cid]
,book.Name
for
xml path( 'Book' ), type
),
c.[Page]
for
xml path( 'Location' ), type
)
from
Card c
left outer join Category book on book.Id = c.BookId
where
c.Id = @cardId
for
xml path( 'Card' ), type
产生
<Card id="2">
<Name>My Card</Name>
<Location>
<Book cid="66">
<Name>My Book</Name> <!-- need to stop My Book from appearing in its own element -->
</Book>
<Page>118</Page>
</Location>
</Card>
和这个查询,它将书籍ID放在书籍元素中(耶!),但将书名放在自己的元素中(嘘!)。
select
c.Id [@id],
c.Name,
(
select
c.BookId [@bookId],
book.Name Book,
c.[Page]
for
xml path( 'Location' ), type
)
from
Card c
left outer join Category book on book.Id = c.BookId
where
c.Id = @cardId
for
xml path( 'Card' ), type
产生
<Card id="2">
<Name>My Card</Name>
<Location bookId="66"> <!-- need bookId to appear in the Book element -->
<Book>My Book</Book>
<Page>118</Page>
</Location>
</Card>
我认为我非常接近,但在这一点上它是盲目的试验和错误,这不是我想要度过我的假期:)任何帮助将不胜感激。谢谢!
编辑 - 2017/01/08 我最终得到了以下查询,它提供了我想要的内容。 Shnugo在下面也提供了一个非常相似的答案,没有使用子选择。
select
c.Id [@id],
c.Name,
(
select
c.BookId [Book/@bookId],
book.Name [Book],
c.Page [Page]
for
xml path( 'Location' ), type
)
from
Card c
inner join Category book on book.Id = c.BookId
for
xml path( 'Card' ), type
答案 0 :(得分:1)
我认为你正在寻找:
如果<Card>
和<Location>
之间没有1:n关系,则无需进行子选择......
DECLARE @Card TABLE(Id INT, Name VARCHAR(100), BookId INT, [Page] INT);
INSERT INTO @Card VALUES(2,'My Card',66,118);
DECLARE @Category TABLE(Id INT,Name VARCHAR(100));
INSERT INTO @Category VALUES(66,'My Book');
SELECT c.Id AS [@id]
,c.Name AS [Name]
,c.BookId AS [Location/Book/@cid]
,book.Name AS [Location/Book]
,c.Page AS [Location/Page]
from
@Card c
left outer join @Category book on book.Id = c.BookId
FOR XML PATH('Card')
结果
<Card id="2">
<Name>My Card</Name>
<Location>
<Book cid="66">My Book</Book>
<Page>118</Page>
</Location>
</Card>
答案 1 :(得分:0)
你可以用XQuery
来做select (
select c.Id [@id], c.Name, book.Name [Book], book.Id [cid], c.Page
from Card c
left outer join Category book on book.Id = c.BookId
where c.Id = @cardId
for xml path('Card'), type
).query('
<Card id="{/Card/@id}">
{/Card/Name}
<Location>
<Book cid="{/Card/cid}">{data(/Card/Book)}</Book>
{/Card/Page}
</Location>
</Card>
')