XML
- Criando tabelas no SQL Server (SqlBulkCopy)
![]() |
Neste artigo eu vou recordar como podemos criar tabelas no SQL Server a partir de arquivos XML usando o SqlBulkCopy e a linguagem C#. |
![]() |
Neste artigo veremos como podemos gerar tabelas no SQL Server a partir de arquivos XML e para isso vamos realizar tarefas básicas como:
Dentre as diversas opções que temos para importar dados de um DataTable para uma Tabela podemos :
Usaremos o SqlBulkCopy para importar dados a partir de um arquivo XML para uma tabela SQL.
A classe SqlBulkCopy fornece funcionalidade similar ao utilitário de linha de comando do Microsoft SQL Server conhecido como bcp. O bcp basicamente era usado para efetuar a cópia de grande volume de dados entre duas base de dados SQL Server.
O SqlBulkcopy vai além, pois permite ser usado também entre DataSets, DataTables , Arrays de objetos DataRow , DataReader, etc. e não somente entre base de dados SQL Server.
Como exemplo vou usar o arquivo funcionarios.xml que possui a seguinte estrutura:
<?xml version="1.0"?>
<funcionarios>
<funcionario>
<codigo>7369</codigo>
<nome>Saulo Barbosa</nome>
<cargo>Administrativo</cargo>
<admissao>17-12-1980</admissao>
</funcionario>
...
<funcionario>
<codigo>7788</codigo>
<nome>Sandra Rocha</nome>
<cargo>Analista</cargo>
<admissao>19-04-1987</admissao>
</funcionario>
.....
<codigo>7934</codigo>
<nome>Miriam Rocha</nome>
<cargo>Supervisora</cargo>
<admissao>23-01-1982</admissao>
</funcionario>
</funcionarios>
|
Com base neste arquivo vamos gerar a tabela no SQL Server com o mesmo nome onde a estrutura da tabela vai copiar os nomes das colunas com base nos elementos : codigo, nome, cargo e adminissao.
Recursos usados
Criando o projeto Windows Forms
Abra o VS 2017 Community e crie um novo projeto do tipo Windows Forms com o nome Xml_Database:
Inclua no projeto uma referência a System.Configuration :
A seguir no formulário Form1.cs inclua os seguintes controles a partir da ToolBox:
Inclua no arquivo App.Config a string de conexão com o banco de dados SQL Server:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
</startup>
<connectionStrings>
<add name="conexaoSQL" connectionString="Data Source=MACORATTI;Initial Catalog=Estudo;
Integrated Security=True" providerName="System.Data.SqlClient"/>
</connectionStrings>
</configuration>
|
Disponha so controles conforme o leiaute da figura abaixo:
![]() |
Implementando o código no formulário
No início do formulário inclua o código abaixo para obter a string de conexão a partir do arquivo App.Config:
string StrCon = ConfigurationManager.ConnectionStrings["conexaoSql"].ToString();
No Evento Click do botão Localizar inclua seguinte código:
private void btnLocalizar_Click(object sender, EventArgs e)
{
// Configurações iniciais do OpenFileDialog
this.ofdlg1.Multiselect = false;
this.ofdlg1.Title = "Selecionar arquivo";
ofdlg1.InitialDirectory = @"C:\dados\xml";
//filtra para exibir somente arquivos xml
ofdlg1.Filter = "XML (*.XML;*.xml)|*.XML;*.xml|" + "Todos (*.*)|*.*";
ofdlg1.CheckFileExists = true;
ofdlg1.CheckPathExists = true;
ofdlg1.FilterIndex = 1;
ofdlg1.RestoreDirectory = true;
ofdlg1.ReadOnlyChecked = true;
ofdlg1.ShowReadOnly = true;
if (ofdlg1.ShowDialog() == DialogResult.OK)
{
try
{
txtArquivo.Text = ofdlg1.FileName;
}
catch (Exception ex)
{
// Não pode carregar o arquivo (problemas de permissão)
MessageBox.Show("Não é possível acessar o arquivo : " + ofdlg1.FileName
+ ". Você pode não ter permissão para ler o arquivo , ou " +
" ele pode estar corrompido.\n\nErro reportado : " + ex.Message);
}
}
}
|
O código acima abre uma caixa de diálogo para selecionar o arquivo XML e atribui o nome à caixa de texto : txtArquivo no formulário.
Agora no evento Click do botão Importar inclua o código abaixo:
private void btnImportar_Click(object sender, EventArgs e)
{
string arquivoXML = txtArquivo.Text;
if (File.Exists(arquivoXML))
{
// Converte o arquivo Xml para um DataTable
DataTable dt = CriaDataTableXML(arquivoXML);
if (dt.Columns.Count == 0)
dt.ReadXml(arquivoXML);
// Cria uma Consulta para criar a tabela no SQL Server
string consultaSQL = CriaConsultaTabela(dt);
SqlConnection con = new SqlConnection(StrCon);
con.Open();
// Deleta a tabela se ela já existir
SqlCommand cmd = new SqlCommand("IF OBJECT_ID('dbo." + dt.TableName + "', 'U') IS NOT NULL
DROP TABLE dbo." + dt.TableName + ";", con);
cmd.ExecuteNonQuery();
// Cria a tabela
cmd = new SqlCommand(consultaSQL , con);
int verifica = cmd.ExecuteNonQuery();
if (verifica != 0)
{
// Copia os dados a partir do DataTable para a tabela SQL
using (var bulkCopy = new SqlBulkCopy(con.ConnectionString, SqlBulkCopyOptions.KeepIdentity))
{
// os nomes da coluna do DataTable usado correspondem aos nomes das colunas da tabela SQL,
// assim usei um laço foreach simples. No entanto, se os nomes das colunas
// não corresponderem, apenas passe qual nome do DataTabel corresponde ao nome da coluna SQL
// em ColumnMappings
foreach (DataColumn col in dt.Columns)
{
bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);
}
bulkCopy.BulkCopyTimeout = 600;
bulkCopy.DestinationTableName = dt.TableName;
bulkCopy.WriteToServer(dt);
}
MessageBox.Show("tabela Criada com Sucesso...");
}
con.Close();
}
}
|
Após a criação da tabela, adicionaremos os dados XML à tabela SQL uasndo o SqlBulkCopy.
A tabela abaixo descreve os membros da enumeração do SqlBulkCopyOptions:
Membro | Descrição |
ChecConstraints | Aplica a verificação de restrições durante o processo de cópia |
Default | Não usa opções para a operação de cópia em massa |
FireTriggers | Permite triggers INSERT serem disparados durante a processo de cópia |
KeepIdentity | Usa valores Identity da tabela fonte ao invés de gerar novos valores de identity baseados na semente da tabela de destino. |
KeepNulls | Retêm valores fontes null |
TableLock | Aplica um lock na tabela para a duração do processo de cópia. O padrão é o lock de linhas. |
UseInternalTransaction | Faz com que cada lote de sql bulkcopy seja executado dentro de uma transação |
O código acima cria a tabela a partir do arquivo XML selecionado e usa dois métodos para realizar essa tarefa:
A seguir temos o código usado em cada um destes métodos:
1- CriaDataTableXML(arquivoXML)
// Converte o arquivo Xml para um DataTable
public DataTable CriaDataTableXML(string arquivoXML)
{
XmlDocument doc = new XmlDocument();
doc.Load(arquivoXML);
DataTable Dt = new DataTable();
try
{
Dt.TableName = GetNomeTabela(arquivoXML);
XmlNode NodoEstructura = doc.DocumentElement.ChildNodes.Cast<XmlNode>().ToList()[0];
pgbar1.Maximum = NodoEstructura.ChildNodes.Count;
pgbar1.Value = 0;
foreach (XmlNode columna in NodoEstructura.ChildNodes)
{
Dt.Columns.Add(columna.Name, typeof(String));
Progresso();
}
XmlNode Filas = doc.DocumentElement;
pgbar1.Maximum = Filas.ChildNodes.Count;
pgbar1.Value = 0;
foreach (XmlNode Fila in Filas.ChildNodes)
{
List<string> Valores = Fila.ChildNodes.Cast<XmlNode>().ToList().Select(x => x.InnerText).ToList();
Dt.Rows.Add(Valores.ToArray());
Progresso();
}
}
catch (Exception ex)
{
throw ex;
}
return Dt;
}
|
Neste código carregamos o arquivo XML e criamos um DataTable com o mesmo nome do arquivo XML obtido pelo método GetNomeTabela().
A seguir criamos a estrutura da tabela com base nos nós XML obtidos, e exibimos o progresso na ProgressBar usando o método Progresso().
Abaixo temos o código destes dois métodos:
// Obtem o nome da tabela a partir do nome do arquivo XML
public string GetNomeTabela(string arquivo)
{
FileInfo fi = new FileInfo(arquivo);
string nomeTabela = fi.Name.Replace(fi.Extension, "");
return nomeTabela;
}
// Exibe a ação da ProgressBar
public void Progresso()
{
if (pgbar1.Value < pgbar1.Maximum)
{
pgbar1.Value++;
int percent = (int)(((double)pgbar1.Value / (double)pgbar1.Maximum) * 100);
pgbar1.CreateGraphics().DrawString(percent.ToString() +
"%", new Font("Arial", (float)8.25, FontStyle.Regular),
Brushes.Black, new PointF(pgbar1.Width / 2 - 10, pgbar1.Height / 2 - 7));
Application.DoEvents();
}
}
|
2- CriaConsultaTabela(dt)
public string CriaConsultaTabela(DataTable table)
{
string sqlsc = "CREATE TABLE " + table.TableName + "(";
pgbar1.Maximum = table.Columns.Count;
pgbar1.Value = 0;
for (int i = 0; i < table.Columns.Count; i++)
{
sqlsc += "[" + table.Columns[i].ColumnName + "]";
string columnType = table.Columns[i].DataType.ToString();
switch (columnType)
{
case "System.Int32":
sqlsc += " int ";
break;
case "System.Int64":
sqlsc += " bigint ";
break;
case "System.Int16":
sqlsc += " smallint";
break;
case "System.Byte":
sqlsc += " tinyint";
break;
case "System.Decimal":
sqlsc += " decimal ";
break;
case "System.DateTime":
sqlsc += " datetime ";
break;
case "System.String":
default:
sqlsc += string.Format(" nvarchar({0}) ", table.Columns[i].MaxLength == -1 ? "max" :
table.Columns[i].MaxLength.ToString());
break;
}
if (table.Columns[i].AutoIncrement)
sqlsc += " IDENTITY(" + table.Columns[i].AutoIncrementSeed.ToString() + "," +
table.Columns[i].AutoIncrementStep.ToString() + ") ";
if (!table.Columns[i].AllowDBNull)
sqlsc += " NOT NULL ";
sqlsc += ",";
Progresso();
}
return sqlsc.Substring(0, sqlsc.Length - 1) + "\n)";
}
|
Neste
código montamos o comando SQL para criar a estrutura da tabela com base nas
informações obtidas do arquivo XML.
Executando o projeto e clicando no botão Localizar temos o seguinte resultado:
Selecionando um arquivo XML e clicando no botão Importar temos o seguinte
resultado:
Verificando no SQL Server o banco de dados Estudo, vemos a tabela funcionarios gerada com os dados obtidos do arquivo XML, conforme figura abaixo:
Pegue o
código do projeto aqui : Xml_Database.zip
"E por que atentas tu
no argueiro que está no olho de teu irmão, e não reparas
na trave que está no teu próprio olho ? "
Lucas 6:41
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Gostou ?
Compartilhe no Facebook
Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
C# - Salvando e Lendo informações em um arquivo XML - Macoratti