2009-12-11 4 views
6

J'ai deux variables xml dire @res, @student dans un proc stocké dans SQL Server 2005.Comment insérer du XML dans un nœud d'un autre XML en utilisant XQuery?

de @res contient

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

@student contient:

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

Je dois insérez le xml de @res dans le noeud Résultat dans la variable @student à l'aide de XQuery.

Comment implémenter cela?

Aidez-nous s'il vous plaît.

+0

Ajout d'une solution d'analyse de chaîne «hacky» qui devrait également fonctionner pour SQL Server 2005 - pas jolie, mais cela devrait fonctionner. –

Répondre

31

Dans SQL Server 2008, il est assez facile:

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 

Cela me donne la sortie:

<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> 

Malheureusement, la possibilité d'appeler .modify() et utiliser un sql:variable dans l'instruction d'insertion a été introduite avec SQL Server 2008 uniquement - ne fonctionne pas dans SQL Server 2005.

Je ne vois pas comment vous pourriez faire cela dans SQL Server 2005, o Ther que de recourir revenir à l'analyse de la chaîne laid et remplacement:

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

Marc

0

Vous pouvez également essayer de revenir à des données relationnelles et de revenir à XML; quelque chose comme:

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 

Retours:

<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> 

Pas exactement votre exemple, mais à proximité.

7

Cela fonctionne dans SQL 2005 et est le plus souvent une solution 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 

Vous pouvez définir votre variable @student à @final à ce moment-là si vous avez besoin de le faire. Le nom de "test" pour le noeud était exactement ce que j'ai choisi d'utiliser. Vous pouvez utiliser n'importe quel nom tant qu'il n'apparaîtra pas déjà dans votre fichier XML.

Fondamentalement, vous venez de jeter les deux chaînes XML ensemble de sorte qu'ils sont tous deux disponibles pour xquery à la fois.

Questions connexes