2009-12-11 10 views
6

Ho due variabili xml dire @res, @student in una stored procedure in SQL Server 2005.Come inserire xml in un nodo in un altro xml utilizzando XQuery?

@res contiene

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

@student contiene:

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

ho bisogno di inserisci l'xml di @res nel nodo Risultato nella variabile @student usando XQuery.

Come implementarlo?

Per favore aiuto.

+0

Aggiunta una soluzione di analisi delle stringhe "hacky" che dovrebbe funzionare anche per SQL Server 2005 - non carina, ma dovrebbe funzionare. –

risposta

31

In SQL Server 2008, è abbastanza 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 

Questo mi dà l'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> 

Purtroppo, la possibilità di chiamare .modify() e utilizzare un sql:variable nell'istruzione INSERT è stata introdotta solo con SQL Server 2008 - non funziona in SQL Server 2005.

Non vedo come è possibile farlo in SQL Server 2005, o ther che ricorrere di nuovo al brutto parsing della stringa e la sostituzione:

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

Marc

0

Si può anche provare a tornare ai dati relazionali e di tornare a xml; qualcosa di simile:

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 

Ritorni:

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

Non esattamente il vostro esempio, ma quasi.

7

Questo funziona in SQL 2005 ed è in gran parte una soluzione 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 

È possibile impostare la variabile @student a @final a quel punto, se avete bisogno di farlo. Il nome di "test" per il nodo era proprio quello che ho scelto di usare. È possibile utilizzare qualsiasi nome a condizione che non sia già presente nel codice XML.

Fondamentalmente è sufficiente lanciare le due stringhe XML in modo che siano entrambe disponibili per xquery contemporaneamente.

Problemi correlati