有没有不用显式使用字段名称的查询XML数据的方法?

时间:2018-06-22 12:10:30

标签: sql sql-server

我想知道是否可以概括此查询,以便用户不需要知道字段名称?

我当前的查询看起来像这样:

USE [VideoGameProject]
DECLARE @myXML = "'<review><rating>97</rating><gameid>2</gameid><reviewdate>11/03/2017</reviewdate><reviewtitle>Super Mario Odyssey : A Masterpiece</reviewtitle><headline>Mario embarks on his greatest adventure yet!</headline></review>';

SELECT
value.value('(/review//rating/node()[1]', 'int') as Rating,
value.value('(/review//gameid/node()[1]', 'int') as GameId,
value.value('(/review//reviewdate/node()[1]', 'nvarchar(max)') as DateOfReview,
value.value('(/review//reviewtitle/node()[1]', 'nvarchar(max)') as TitleOfReview,
value.value('(/review//headline/node()[1]', 'nvarchar(max)') as Headline

FROM GameData;

我希望做一个通用查询,不需要显式地写所有字段名,例如SELECT *等价物?

我看到上面的查询容易出错。我了解@myXML变量不是必需的,但想提供参考。

如果有人可以帮助,那就太好了。

1 个答案:

答案 0 :(得分:0)

是的,您可以使用节点的顺序位置(元素和属性)。

您需要对此进行调整,但是看起来像这样...

DECLARE @myXML AS xml
SET @myXML  = '
<review>
    <rating>97</rating>
    <gameid>2</gameid>
    <reviewdate>11/03/2017</reviewdate>
    <reviewtitle>Super Mario Odyssey : A Masterpiece</reviewtitle>
    <headline>Mario embarks on his greatest adventure yet!</headline>
</review>
';

SELECT @myXML.query('/node()[1]/node()[1]/node()[1]') AS [Rating]
SELECT @myXML.query('/node()[1]/node()[2]/node()[1]') AS [GameId]
SELECT @myXML.query('/node()[1]/node()[3]/node()[1]') AS DateOfReview
SELECT @myXML.query('/node()[1]/node()[4]/node()[1]') AS TitleOfReview
SELECT @myXML.query('/node()[1]/node()[5]/node()[1]') AS Headline

而且,如果您的XML不在变量中,则可以直接从表中查询它。

一个用于演示的表:

CREATE TABLE #foo (id int identity(1,1), things xml)

DECLARE @myXML AS xml
SET @myXML  = '
<review>
    <rating>97</rating>
    <gameid>2</gameid>
    <reviewdate>11/03/2017</reviewdate>
    <reviewtitle>Super Mario Odyssey : A Masterpiece</reviewtitle>
    <headline>Mario embarks on his greatest adventure yet!</headline>
</review>
';

INSERT INTO #foo (things) VALUES (@myXML);

现在,我们有了一个包含XML数据记录的表。这是选择它的一种方法...

SELECT things.value('/node()[1]/node()[1]/node()[1]', 'varchar(max)') AS [Rating]
FROM #foo

这是另一个...

SELECT things.query('/node()[1]/node()[1]/node()[1]') AS [Rating]
FROM #foo