Gerando XML no SQL Server – Arte do FOR XML RAW

Seguindo com a Arte do FOR XML, nos deparamos com o FOR XML RAW, que não se diferencia muito do FOR XML AUTO, mas aproveitamos este artigo para demonstrar outros aspectos interessantes tanto do FOR XML RAW quando do FOR XML AUTO (campos nulos, tipos binários e schemas).

Como primeiro passo, temos uma consulta RAW básica:

SELECT TOP (5)
	  FirstName
	, LastName
FROM
	Person.Contact
FOR XML RAW
<row FirstName="Gustavo" LastName="Achong" />
<row FirstName="Catherine" LastName="Abel" />
<row FirstName="Kim" LastName="Abercrombie" />
<row FirstName="Humberto" LastName="Acevedo" />
<row FirstName="Pilar" LastName="Ackerman" />

Seguida de outra um pouco mais customizada:

SELECT TOP (5)
	  [Name] = FirstName + ', ' + LastName
FROM
	Person.Contact
FOR XML RAW('Contact')
	, ELEMENTS
	, ROOT('Person')
<Person>
  <Contact>
    <Name>Gustavo, Achong</Name>
  </Contact>
  <Contact>
    <Name>Catherine, Abel</Name>
  </Contact>
  <Contact>
    <Name>Kim, Abercrombie</Name>
  </Contact>
  <Contact>
    <Name>Humberto, Acevedo</Name>
  </Contact>
  <Contact>
    <Name>Pilar, Ackerman</Name>
  </Contact>
</Person>

Uma questão importante de se verificar é o comportamento da geração do XML (AUTO e RAW) quando tratamos de campos NULL, assim temos a alternativa de não gerar os nós nulos (comportamento padrão):

SELECT TOP (5)
	  [Name] = FirstName + ', ' + LastName
	, MiddleName
FROM
	Person.Contact
FOR XML RAW('Contact')
	, ELEMENTS ABSENT
	, ROOT('Person')
<Person>
  <Contact>
    <Name>Gustavo, Achong</Name>
  </Contact>
  <Contact>
    <Name>Catherine, Abel</Name>
    <MiddleName>R.</MiddleName>
  </Contact>
  <Contact>
    <Name>Kim, Abercrombie</Name>
  </Contact>
  <Contact>
    <Name>Humberto, Acevedo</Name>
  </Contact>
  <Contact>
    <Name>Pilar, Ackerman</Name>
  </Contact>
</Person>

Ou utilizar XSINIL para que exista uma representação destes nós nulos:

SELECT TOP (5)
	  [Name] = FirstName + ', ' + LastName
	, MiddleName
FROM
	Person.Contact
FOR XML RAW('Contact')
	, ELEMENTS XSINIL 
	, ROOT('Person')
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Contact>
    <Name>Gustavo, Achong</Name>
    <MiddleName xsi:nil="true" />
  </Contact>
  <Contact>
    <Name>Catherine, Abel</Name>
    <MiddleName>R.</MiddleName>
  </Contact>
  <Contact>
    <Name>Kim, Abercrombie</Name>
    <MiddleName xsi:nil="true" />
  </Contact>
  <Contact>
    <Name>Humberto, Acevedo</Name>
    <MiddleName xsi:nil="true" />
  </Contact>
  <Contact>
    <Name>Pilar, Ackerman</Name>
    <MiddleName xsi:nil="true" />
  </Contact>
</Person>

Campos binários também podem ser problemáticos, exemplo o seguinte erro:

SELECT TOP (1)
	ProductPhotoID
	, ThumbNailPhoto
FROM
	Production.ProductPhoto
FOR XML RAW

Msg 6829, Level 16, State 1, Line 1
FOR XML EXPLICIT and RAW modes currently do not support addressing binary data as URLs in column ‘ThumbNailPhoto’. Remove the column, or use the BINARY BASE64 mode, or create the URL directly using the ‘dbobject/TABLE[@PK1=”V1″]/@COLUMN’ syntax.

Assim, utilizamos das declarações BINARY BASE64 para tratar este problema:

SELECT TOP (1)
	ProductPhotoID
	, ThumbNailPhoto
FROM
	Production.ProductPhoto
FOR XML RAW
	, BINARY BASE64
<row ProductPhotoID="1" ThumbNailPhoto="R0lGODlhUAA..." />

Por fim, temos a necessidade de gerar Schemas ou alguma forma de representação dos tipos de dados que estão presentes no XML, onde podemos utilizar do XMLDATA para uma representação simples dos dados:

SELECT TOP (1)
	  [Name] = FirstName + ', ' + LastName
	, [Email] = EmailAddress
FROM
	Person.Contact
FOR XML RAW
	, XMLDATA
<Schema name="Schema2" xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <ElementType name="row" content="empty" model="closed">
    <AttributeType name="Name" dt:type="string" />
    <AttributeType name="Email" dt:type="string" />
    <attribute type="Name" />
    <attribute type="Email" />
  </ElementType>
</Schema>
<row xmlns="x-schema:#Schema2" Name="Gustavo, Achong" Email="gustavo0@adventure-works.com" />

Ou XMLSCHEMA, para a declaração mais apropriada com Xml Schema definition language (XSD):

SELECT TOP (1)
	  [Name] = FirstName + ', ' + LastName
	, [Email] = EmailAddress
FROM
	Person.Contact
FOR XML RAW('Contact')
	, ROOT('Person')
	, XMLSCHEMA('PersonContact')
<Person>
  <xsd:schema targetNamespace="PersonContact" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified">
    <xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd" />
    <xsd:element name="Contact">
      <xsd:complexType>
        <xsd:attribute name="Name" use="required">
          <xsd:simpleType>
            <xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreNonSpace IgnoreKanaType IgnoreWidth" sqltypes:sqlCollationVersion="2">
              <xsd:maxLength value="102" />
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:attribute>
        <xsd:attribute name="Email">
          <xsd:simpleType>
            <xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreNonSpace IgnoreKanaType IgnoreWidth" sqltypes:sqlCollationVersion="2">
              <xsd:maxLength value="50" />
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:attribute>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <Contact xmlns="PersonContact" Name="Gustavo, Achong" Email="gustavo0@adventure-works.com" />
</Person>

3 pensamentos sobre “Gerando XML no SQL Server – Arte do FOR XML RAW

  1. Pingback: Arte do FOR XML – Resumo « SQL From Hell.com

  2. Pingback: Extraindo informações de arquivo XML para o SQL Server « Alex Souza

  3. Pingback: Como atribuir a uma variável no SQL Server, o valor de uma consulta FOR XML | SQL From Hell.com

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s