C# - Armazenando XML no SQL Server (revisão)


Você já precisou armazenar o conteúdo de um arquivo XML em um banco de dados relacional ?

Embora o SQL Server, na sua versão atual, possua um ótimo suporte para XML, dependendo da versão usada você não tem esses recursos disponíveis. E então, neste caso, como você pode resolver este problema ?

É isso que veremos neste artigo.

Dentre os recursos XML disponíveis pelo SQL Server podemos citar:

Nota: A XQuery é uma linguagem que usa a estrutura XML de forma a expressar consultas sobre dados no formato XML. Os dados não precisam estar armazenados em arquivos XML, ou simplesmente no formato XML. Você pode pensar na XQuery como sendo uma linguagem equivalente a SQL que pode ser usada para tratar informações XML.

Com isso podemos concluir que existem dois tipos de colunas XML : tipada e não-tipada.

Para armazenar documentos XML nas versões anteriores do SQL Server você pode usar os tipos de dados textos como: VARCHAR, NVARCHAR, TEXT e NTEXT.

Este artigo mostra como armazenar documentos XML em colunas não-tipadas em um banco de dados SQL Server usando o tipo de dados NVARCHAR.

Criando o banco de dados, a tabela no SQL Server e o arquivo XML

Para o nosso exemplo vamos criar um banco de dados SQL Server chamado Cadastro.mdf usando o SQL Server 2012 Express LocalDB e definir uma tabela chamada DocumentosXML com a seguinte estrutura:

Para visualizar as conexões com banco de dados clique no menu VIEW clique em Other Windows -> DataBase Explorer para abrir a DataBase Explorer exibindo as conexões existentes com as fontes de dados:

Clique com o botão direito do mouse sobre Data Connections e selecione Add Connections;

Informe o nome do servidor : (LocalDB)\v11.0 e o nome do banco de dados que deseja criar ou ao qual deseja se conectar:

O Microsoft SQL Server 2012 Express LocalDB é um modo de execução do SQL Server Express destinado a desenvolvedores de programas.

A instalação do LocalDB copia um conjunto mínimo de arquivos necessários para iniciar o mecanismo de Banco de Dados do SQL Server.

Quando o LocalDB é instalado, os desenvolvedores iniciam uma conexão usando uma cadeia de conexão especial.

Na conexão, a infraestrutura necessária do SQL Server é criada e iniciada automaticamente, permitindo que o aplicativo use o banco de dados sem tarefas de configuração complexas ou demoradas.

O Developer Tools pode fornecer aos desenvolvedores um mecanismo de Banco de Dados do SQL Server que permite que eles gravem  e testem o código Transact-SQL sem precisar gerenciar uma instância de servidor inteira do SQL Server. Uma instância do SQL Server Express LocalDB é gerenciada com o utilitário SqlLocalDB.exe.

O SQL Server Express LocalDB deve ser usado em lugar do recurso de instância de usuário do SQL Server Express, que ficou obsoleto.

Expanda os objetos da conexão e clique com o botão direito do mouse sobre Tables;

No menu suspenso clique em Add New Table;

Na janela do descritor SQL defina a estrutura da tabela com os seguintes campos:

Se você clicar sobre a conexão com o banco de dados Gedoc poderá ver na janela de propriedades a string de conexão definida:

Vamos criar um arquivo XML para usar como exemplo no projeto.

No menu PROJECT clique em Add New Item e selecione Visual C# Items -> XML File e informe o nome Funcionarios.xml clique em Add;

A seguir defina a estrutura do arquivo Funcionarios.xml conforme mostra a figura abaixo:

Vamos copiar este arquivo para um pasta local: c:\dados.(vou deixar o xml no projeto também)

Criando o projeto no Visual Studio 2012 for Windows Desktop

Abra o Visual Studio 2012 for Windows desktop e clique em New Project;

Clique em Visual C# -> Windows e selecione Windows Forms Application informando o nome XML_SqlServerNaoTipado e clicando no botão OK;

No formulário form1.cs do projeto vamos incluir os seguintes controles:

Leiaute do formulário:

A seguir defina os seguintes namespaces no formulário:

using System;
using System.Data;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Xml;

1- Armazenando o XML

No evento Click do botão btnArmazenarXML inclua o código abaixo:

private void btnArmazenaXML_Click(object sender, EventArgs e)
        {
            //define a string de conexão e a instrução SQL
            string sqlConnectString = @"Data Source=(LocalDB)\v11.0;Initial Catalog=Cadastro;Integrated Security=True";
            string instrucaoSQL = "SELECT Id, textoXML FROM DocumentosXML";
            try
            {
                // cria um the data adapter e um command builder
                SqlDataAdapter da = new SqlDataAdapter(instrucaoSQL, sqlConnectString);
                SqlCommandBuilder cb = new SqlCommandBuilder(da);

                // Cria um DataTable e obtem os dados e o schema
                da.FillSchema(dt, SchemaType.Source);
                da.Fill(dt);

                // carrega o arquivo xml em um XmlDocument
                string arquivoXML = @"c:\dados\Funcionarios.xml";
                XmlDocument documentoXML = new XmlDocument();
                documentoXML.Load(arquivoXML);
                // Cria uma nova  linha a partir do documento XML
                DataRow linhaTabela = dt.NewRow();
                //atribui o XML a coluna TextoXMl da tabela 
                linhaTabela["TextoXml"] = documentoXML.InnerXml;
                dt.Rows.Add(linhaTabela);
                //atualiza o banco de dados
                da.Update(dt);
                //limpa a tabela
                dt.Clear();
                MessageBox.Show("Documento XML armazenado com sucesso!!!", "OK", MessageBoxButtons.OK);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erro : " + ex.Message.ToString(), "Erro", MessageBoxButtons.OK);
            }
        }

O código cria um DataTable e usa um DataAdapter para preencher o datatable com dados e esquema a partir da tabela DocumentosXML.

Estamos criando uma instância da classe XmlDocument que representa o documento XML e contém um método Load para carregar o documento a partir de um arquivo, fluxo ou XmlReader.

O arquivo Funcionarios.xml é carregado usando o método Load do XmlDocument.

Criamos um nova linha no DataTable e usando a propriedade InnerText, que obtêm os valores concatenados do nó e todos os seus nós filhos , e estamos armazenando o valor no campo TextoXML da tabela.

A seguir atualizamos a tabela usando o método Update do Adapter e limpamos o datatable.

Se abrirmos o banco de dados e espiarmos a tabela veremos os dados armazenados conforme a figura a seguir:

2- Exibindo o XML gerado

No evento Click do botão btnExibirXML digite o código a seguir:

 private void btnExibirXML_Click(object sender, EventArgs e)
        {
            string sqlConnectString = @"Data Source=(LocalDB)\v11.0;Initial Catalog=Cadastro;Integrated Security=True";
            string instrucaoSQL = "SELECT Id, textoXML FROM DocumentosXML";

            try
            {
                //  cria um the data adapter e um command builder
                SqlDataAdapter da = new SqlDataAdapter(instrucaoSQL, sqlConnectString);
                SqlCommandBuilder cb = new SqlCommandBuilder(da);

                //obtem o esquema e os dados do datatable
                da.FillSchema(dt, SchemaType.Source);
                da.Fill(dt);

                // carrega o campo TextoXML da tabela do banco de dados e localiza a linha com id igual a 1
                DataRow linhaTabelaDestino = dt.Rows.Find(1);
                XmlDocument documentoXMLDestino = new XmlDocument();
                documentoXMLDestino.LoadXml(linhaTabelaDestino.Field<string>("TextoXML"));

                // exibe o conteúdo XML no formulário
                txtXML.Text = documentoXMLDestino.InnerXml;
                
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erro : " + ex.Message.ToString(), "Erro", MessageBoxButtons.OK);
            }
        }

O código usa a mesma string de conexão e a instrução SQL.

Localizamos a linha da tabela cujo campo id possui valor igual a 1 e criamos um nova instância da classe XmlDocument que representa o documento XML.

A seguir usamos o método LoadXml carrega o documento XML de uma string específica, no caso o valor do campo TextoXML.

Usamos propriedade InnerXML que obtém ou define a marcação que representa apenas os nós filho deste nó para exibir o conteúdo XML da tabela no controle TextBox- txtXML:

Pegue o projeto completo aqui: XML_SqlServerNaoTipado.zip

Mateus 6:24 Ninguém pode servir a dois senhores; porque ou há de odiar a um e amar o outro, ou há de dedicar-se a um e desprezar o outro. Não podeis servir a Deus e às riquezas.

Veja os Destaques e novidades do SUPER DVD Visual Basic  (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Veja mais sistemas completos para a plataforma .NET no Super DVD .NET , confira...

Quer aprender C# ??

Chegou o Super DVD C#  com exclusivo material de suporte e vídeo aulas com curso básico sobre C#.

Veja também os Cursos com vídeo aulas e projetos exemplos:

    Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti