SQL Server - 基于连接替换XML变量中的文本

时间:2013-04-02 19:33:57

标签: sql xml sql-server-2008

对于我的情况,我有类似于以下的XML:

DECLARE @MyXML XML

SET @MyXML = 
  '
  <Students>
    <Student>
      <Nickname>Cat</Nickname>
      <Name>Catherine</Name>
    </Student>
    <Student>
      <Nickname>Cat</Nickname>
      <Name>Joseph</Name>
    </Student>
  </Students>
  '

SELECT  T.Students.value('Nickname[1]', 'varchar(20)')
FROM    @MyXML.nodes('/Students/Student[Nickname = "Cat"]') T(Students)
JOIN    dbo.MyStudents CLASS ON T.Students.value('Name[1]', 'varchar(20)') = CLASS.StudentName

我想更新从此SELECT语句返回的记录,将Nickname替换为CLEARED。所以,如果dbo.MyStudents有约瑟夫而不是凯瑟琳,那么得到的@MyXML变量将是:

  <Students>
    <Student>
      <Nickname>Cat</Nickname>
      <Name>Catherine</Name>
    </Student>
    <Student>
      <Nickname>CLEARED</Nickname>
      <Name>Joseph</Name>
    </Student>
  </Students>

有没有办法直接修改XML变量?或者我需要将XML变量放入临时表并在临时表上执行.modify吗?

到目前为止,我发现的示例没有基于连接的.modify条件更新。

1 个答案:

答案 0 :(得分:0)

试试这个例子。有关详细信息,请参阅Syntax of the FOR XML Clause

-- sample @MyStudents table
declare @MyStudents table (StudentName varchar(90), NickName varchar(90));
insert @MyStudents values('Kent', '');
insert @MyStudents values('Robert', 'Bobby');
insert @MyStudents values('Lisa', 'LB');
insert @MyStudents values('Venkat', 'Big Cat');
insert @MyStudents values('Catherine', 'Cat');
insert @MyStudents values('Joseph', 'Joey');

DECLARE @MyXML XML
SET @MyXML = 
  '<Students>
    <Student>
      <Nickname>Cat</Nickname>
      <Name>Catherine</Name>
    </Student>
    <Student>
      <Nickname>Joey</Nickname>
      <Name>Joseph</Name>
    </Student>
    <Student>
      <Nickname>Bonzo</Nickname>
      <Name>Clifford</Name>
    </Student>
  </Students>'

select @MyXML = (
    select ( 
        select * from (
            -- set existing @MyStudent records to CLEARED
            select 
                'CLEARED' as NickName,
                T.Students.value('Name[1]', 'varchar(20)') as Name
            from @MyXML.nodes('/Students/Student') T(Students)
            join @MyStudents CLASS ON T.Students.value('Name[1]', 'varchar(20)') = CLASS.StudentName
            union
            -- get students that aren't in @MyStudents table
            select 
                T.Students.value('Nickname[1]', 'varchar(20)') as NickName,
                T.Students.value('Name[1]', 'varchar(20)') as Name
            from @MyXML.nodes('/Students/Student') T(Students)
            where not exists(select 1 from @MyStudents s where s.StudentName = T.Students.value('Name[1]', 'varchar(20)'))
    ) as t1
    for xml path('Student'), type)
for xml path('Students'), type)