如何使用 XQuery 将 xml 插入另一个 xml 中的节点?

发布于 2024-08-14 12:38:06 字数 571 浏览 1 评论 0原文

我有两个 xml 变量,比如 SQL Server 2005 中的存储过程中的 @res、@student。

@res contains

<Subject>English</Subject>
<Marks>67</Marks>
<Subject>Science</Subject>
<Marks>75</Marks>

@student contains:

<Student> 
   <Name>XYZ</Name>
   <Roll>15</Roll>
   <Result />
   <Attendance>50</Attendance>
</Student>

我需要将 @res 的 xml 插入到 @student 中的节点 Result 中使用 XQuery 的变量。

如何实施?

请帮忙。

I have two xml variable say @res, @student in a stored proc in SQL server 2005.

@res contains

<Subject>English</Subject>
<Marks>67</Marks>
<Subject>Science</Subject>
<Marks>75</Marks>

@student contains:

<Student> 
   <Name>XYZ</Name>
   <Roll>15</Roll>
   <Result />
   <Attendance>50</Attendance>
</Student>

I need to insert the xml of @res into the node Result in @student variable using XQuery.

How to implement that?

Please help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

如果没结果 2024-08-21 12:38:06

在 SQL Server 2008 中,这非常简单:

DECLARE @res XML = '<Subject>English</Subject>
<Marks>67</Marks>
<Subject>Science</Subject>
<Marks>75</Marks>'


DECLARE @student XML = '<Student> 
   <Name>XYZ</Name>
   <Roll>15</Roll>
   <Result />
   <Attendance>50</Attendance>
</Student>'


SET @student.modify('insert sql:variable("@res") as first into (/Student/Result)[1]')

SELECT @student

这给了我输出:

<Student>
  <Name>XYZ</Name>
  <Roll>15</Roll>
  <Result>
    <Subject>English</Subject>
    <Marks>67</Marks>
    <Subject>Science</Subject>
    <Marks>75</Marks>
  </Result>
  <Attendance>50</Attendance>
</Student>

不幸的是,调用 .modify() 并在插入语句中使用 sql:variable 的能力是仅在 SQL Server 2008 中引入 - 在 SQL Server 2005 中不起作用。

除了求助于丑陋的字符串解析和替换之外,我不知道如何在 SQL Server 2005 中执行此操作:

SET @student = 
    CAST(REPLACE(CAST(@student AS VARCHAR(MAX)), 
                 '<Result/>', 
                 '<Result>' + CAST(@res AS VARCHAR(MAX)) + '</Result>') AS XML)

Marc

In SQL Server 2008, it's pretty easy:

DECLARE @res XML = '<Subject>English</Subject>
<Marks>67</Marks>
<Subject>Science</Subject>
<Marks>75</Marks>'


DECLARE @student XML = '<Student> 
   <Name>XYZ</Name>
   <Roll>15</Roll>
   <Result />
   <Attendance>50</Attendance>
</Student>'


SET @student.modify('insert sql:variable("@res") as first into (/Student/Result)[1]')

SELECT @student

That gives me the output:

<Student>
  <Name>XYZ</Name>
  <Roll>15</Roll>
  <Result>
    <Subject>English</Subject>
    <Marks>67</Marks>
    <Subject>Science</Subject>
    <Marks>75</Marks>
  </Result>
  <Attendance>50</Attendance>
</Student>

Unfortunately, the ability to call .modify() and use a sql:variable in the insert statement was introduced with SQL Server 2008 only - doesn't work in SQL Server 2005.

I don't see how you could do this in SQL Server 2005, other than resorting back to ugly string parsing and replacement:

SET @student = 
    CAST(REPLACE(CAST(@student AS VARCHAR(MAX)), 
                 '<Result/>', 
                 '<Result>' + CAST(@res AS VARCHAR(MAX)) + '</Result>') AS XML)

Marc

云胡 2024-08-21 12:38:06

这将在 SQL 2005 中工作,并且主要是一个 xquery 解决方案:

DECLARE @res xml

SET @res = 
'<Subject>English</Subject>
<Marks>67</Marks>
<Subject>Science</Subject>
<Marks>75</Marks>'

DECLARE @student xml
SET @student =
'<Student>
   <Name>XYZ</Name>
   <Roll>15</Roll>
   <Result />
   <Attendance>50</Attendance>
</Student>'

DECLARE @final XML

SET @final = CAST(CAST(@student AS VARCHAR(MAX)) + '<test>' + CAST(@res AS VARCHAR(MAX)) + '</test>' AS XML)

SET @final.modify('insert /test/* into (/Student/Result)[1]')
SET @final.modify('delete /test')

SELECT @final

如果需要的话,您可以在此时将 @student 变量设置为 @final。节点的“test”名称正是我选择使用的名称。您可以使用任何名称只要它尚未出现在您的 XML 中即可。

基本上只需将两个 XML 字符串放在一起,以便它们同时可用于 xquery。

This will work in SQL 2005 and is mostly an xquery solution:

DECLARE @res xml

SET @res = 
'<Subject>English</Subject>
<Marks>67</Marks>
<Subject>Science</Subject>
<Marks>75</Marks>'

DECLARE @student xml
SET @student =
'<Student>
   <Name>XYZ</Name>
   <Roll>15</Roll>
   <Result />
   <Attendance>50</Attendance>
</Student>'

DECLARE @final XML

SET @final = CAST(CAST(@student AS VARCHAR(MAX)) + '<test>' + CAST(@res AS VARCHAR(MAX)) + '</test>' AS XML)

SET @final.modify('insert /test/* into (/Student/Result)[1]')
SET @final.modify('delete /test')

SELECT @final

You can set your @student variable to @final at that point if you need to do that. The name of "test" for the node was just what I chose to use. You can use any name as long as it will not already appear in your XML.

You basically just throw the two XML strings together so that they are both available to xquery at once.

等你爱我 2024-08-21 12:38:06

您也可以尝试返回到关系数据而不是返回到 xml;类似于:

DECLARE @res xml = 
'<result>
  <StudentID>1</StudentID>
  <Subject>English</Subject>
  <Marks>67</Marks>
</result>
<result>
  <StudentID>1</StudentID>
  <Subject>Science</Subject>
  <Marks>75</Marks>
</result>'

DECLARE @student xml =
'<Student> 
   <StudentID>1</StudentID>
   <Name>XYZ</Name>
   <Roll>15</Roll>
   <Attendance>50</Attendance>
</Student>'

;
WITH  cte_1
        AS ( SELECT t.c.value('StudentID[1]', 'int') AS [StudentID]
                   ,t.c.value('Subject[1]', 'varchar(50)') AS [Subject]
                   ,t.c.value('Marks[1]', 'int') AS [Marks]
             FROM   @res.nodes('/result') AS t ( c )
           ),
      cte_2
        AS ( SELECT t.c.value('StudentID[1]', 'int') AS [StudentID]
                   ,t.c.value('Name[1]', 'varchar(50)') AS [Name]
                   ,t.c.value('Roll[1]', 'int') AS [Roll]
                   ,t.c.value('Attendance[1]', 'int') AS [Attendance]
             FROM   @student.nodes('/Student') AS t ( c )
           )
  SELECT  student.StudentID
         ,student.[Name]
         ,student.Roll
         ,student.Attendance
         ,( SELECT  result.[Subject]
                   ,result.Marks
            FROM    cte_1 AS result
            WHERE   student.StudentID = result.StudentID
          FOR
            XML AUTO
               ,TYPE
               ,ELEMENTS
          )
  FROM    cte_2 AS student
FOR     XML AUTO
           ,ELEMENTS

Returns:

<student>
  <StudentID>1</StudentID>
  <Name>XYZ</Name>
  <Roll>15</Roll>
  <Attendance>50</Attendance>
  <result>
    <Subject>English</Subject>
    <Marks>67</Marks>
  </result>
  <result>
    <Subject>Science</Subject>
    <Marks>75</Marks>
  </result>
</student>

不完全是您的示例,但很接近。

You may also try to go back to relational data and than back to xml; something like:

DECLARE @res xml = 
'<result>
  <StudentID>1</StudentID>
  <Subject>English</Subject>
  <Marks>67</Marks>
</result>
<result>
  <StudentID>1</StudentID>
  <Subject>Science</Subject>
  <Marks>75</Marks>
</result>'

DECLARE @student xml =
'<Student> 
   <StudentID>1</StudentID>
   <Name>XYZ</Name>
   <Roll>15</Roll>
   <Attendance>50</Attendance>
</Student>'

;
WITH  cte_1
        AS ( SELECT t.c.value('StudentID[1]', 'int') AS [StudentID]
                   ,t.c.value('Subject[1]', 'varchar(50)') AS [Subject]
                   ,t.c.value('Marks[1]', 'int') AS [Marks]
             FROM   @res.nodes('/result') AS t ( c )
           ),
      cte_2
        AS ( SELECT t.c.value('StudentID[1]', 'int') AS [StudentID]
                   ,t.c.value('Name[1]', 'varchar(50)') AS [Name]
                   ,t.c.value('Roll[1]', 'int') AS [Roll]
                   ,t.c.value('Attendance[1]', 'int') AS [Attendance]
             FROM   @student.nodes('/Student') AS t ( c )
           )
  SELECT  student.StudentID
         ,student.[Name]
         ,student.Roll
         ,student.Attendance
         ,( SELECT  result.[Subject]
                   ,result.Marks
            FROM    cte_1 AS result
            WHERE   student.StudentID = result.StudentID
          FOR
            XML AUTO
               ,TYPE
               ,ELEMENTS
          )
  FROM    cte_2 AS student
FOR     XML AUTO
           ,ELEMENTS

Returns:

<student>
  <StudentID>1</StudentID>
  <Name>XYZ</Name>
  <Roll>15</Roll>
  <Attendance>50</Attendance>
  <result>
    <Subject>English</Subject>
    <Marks>67</Marks>
  </result>
  <result>
    <Subject>Science</Subject>
    <Marks>75</Marks>
  </result>
</student>

Not exactly your example, but close.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文