2017-03-09 12 views
2

우리 표는 다음과 같이 우리는이 테이블에서 XML 형식을 원하는 SQL 쿼리

StudentNo Name Subject Mark Grade 
1   John English 41  A 
1   John Hindi 42  B 

같다.

<Student> 
    <Name>John</Name> 
    <Subject> 
    <English> 
      <Mark>41</Mark> 
      <Grade>A</Grade> 
    </English> 
    <Hindi> 
      <Mark>42</Mark> 
      <Grade>B</Grade> 
    </Hindi> 
</Subject> 
<Student> 

여기서 주제 이름 노드는 동적으로 생성되어야합니다.

미리 답변 해 주셔서 감사합니다.

답변

2

이것은 매우 비슷하기 때문에 SQL Data as XML Element과 중복됩니다.하지만 이것이 가장 좋은 아이디어가 아닌 이유에 대해 좀 더 설명하고 싶습니다. 그 질문에 대한 나의 대답에서, 나는 당신이 이것을 할 수있는 정말로 해커 같은 방법을 보여 주지만 그것은 최선의 생각이 아니다.

귀하의 XML은 스키마를 생성하는 것이 거의 불가능합니다. 해당 XML의 사용자는 어떤 값이 요소로 나타날지 절대 알 수 없습니다. 동적 요소를 만들려고하기보다는 일종의 속성을 사용해야합니다. 비록 당신이 당신의 소비자를 위해 가장 잘 이해할 수있는 어떤 속성이라도 고를 수있는 평범한 옛 속성을 사용하고 있습니다 만, xsi:type을 사용하여 XML 형식으로 추상 형식을 만들 수도 있습니다. 그 XML에 대한 쿼리는 다음과 같습니다

declare @subjects TABLE(studentno int, name varchar(10), subjecT varchar(10), mark int, grade char(1)) 

INSERT @subjects 
VALUES 
(1, 'John','English', 41,'A'), 
(1, 'John','Hindi', 42,'B') 

select 
    s.Name 

    ,(SELECT 
     s2.Subject as '@type' 
     ,s2.Mark 
     ,s2.Grade 
    FROM @subjects s2 
    WHERE s2.studentno = s.studentno 
    FOR XML PATH('Subject'), ROOT('Subjects'), TYPE) 
from @subjects s 
GROUP BY s.name, s.studentno 
FOR XML PATH('Student') 

는 생산 :

<Student> 
    <Name>John</Name> 
    <Subjects> 
    <Subject type="English"> 
     <Mark>41</Mark> 
     <Grade>A</Grade> 
    </Subject> 
    <Subject type="Hindi"> 
     <Mark>42</Mark> 
     <Grade>B</Grade> 
    </Subject> 
    </Subjects> 
</Student> 

이 XML들이, 예를 들어, 주제를 반복 할 수 소비자에 의해 이해를 할 수있을 것입니다 어떤 주제를 모르고 거기에있을 수도 있고 Subjects의 모든 직계 자식이 실제로 주체이고 스키마의 새 버전에 추가 된 다른 유형의 노드가 아니라고 가정 할 필요는 없습니다.

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 

    <xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates /> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Subject"> 
     <xsl:element name="{@type}"> 
      <xsl:apply-templates /> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="Subjects"> 
     <xsl:element name="Subject"> 
      <xsl:apply-templates /> 
     </xsl:element> 
    </xsl:template> 
</xsl:transform> 

당신에게

<?xml version="1.0" encoding="UTF-8"?> 
<Student> 
    <Name>John</Name> 
    <Subject> 
     <English> 
     <Mark>41</Mark> 
     <Grade>A</Grade> 
     </English> 
     <Hindi> 
     <Mark>42</Mark> 
     <Grade>B</Grade> 
     </Hindi> 
    </Subject> 
</Student> 

를 가져옵니다 당신이 정말 그 출력을해야하는 경우


, 나는 예를 들면, 당신의 형식으로 위의 출력을 변환하는 XSLT를 사용하는 것을 선호 것 하지만 SQL Server에서는이 작업을 완전히 수행 할 수 없습니다. XML 문자열을 작성하고 XML로 캐스팅해야합니다. 다른 대답과 같습니다.

+0

그러나 우리는 다음과 같은 형식 B에 정확하게 XML이 필요

+0

이 경우 SQL에서 나오는 것을 처리하기 위해 XSLT 스타일 시트를 만들 것입니다. 제 다른 대답을 살펴보십시오. SQL Server에서도 가능하지만 매우 추악합니다.XML 스트링을 수동으로 작성하여 XML로 변환해야합니다.'FOR XML' 구조 중 어느 것도 당신이하려는 것을 지원하지 않습니다. –

+0

변환 할 수있는 XSLT의 예제를 추가했습니다. –