SALVAR DADOS EM MYSQL
Olá pessoal!!
Vou ter diariamente aproximadamente 20.000 linhas em um datagrid que precisarei salvar em um bando de dados mysql. Fiz um teste percorrendo linha a linha e salvando no BD mas isso leva uma eternidade. Existe algum jeito de salvar tudo de uma vez só, sem ser linha a linha??
Vou ter diariamente aproximadamente 20.000 linhas em um datagrid que precisarei salvar em um bando de dados mysql. Fiz um teste percorrendo linha a linha e salvando no BD mas isso leva uma eternidade. Existe algum jeito de salvar tudo de uma vez só, sem ser linha a linha??
Sim. Você pode usar OOP, criar uma lista de objetos e um método que converta a lista em um comandos SQL maiores, algo em torno de 100 registros por operação. Assim:
Não se percorre grids, se modifica dados, por isso que se usa OOP, o grid, é apenas o visualizador dos dados.
INSERT INTO Tabela (a, b, c) VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9)
Não se percorre grids, se modifica dados, por isso que se usa OOP, o grid, é apenas o visualizador dos dados.
Me perde mas não entendi Kerplunk. Os dados iniciais estão em um arquivo excel que eu carrego, mostro em um datagrid, faço algumas alterações e salvo tudo em um BD. Como fazer o que você sugeriu sem percorrer o datagrid para reunir as linhas e salvar no MySQL???
MLALEX,
Acho que o KERPLUNK quis dizer está mais detalhadamente sendo explicado aqui:
http://pt.wingwit.com/P/php-mysql-programming/92467.html#.VecgXsvlv5w
[][ô]s,
Tunusat.
Acho que o KERPLUNK quis dizer está mais detalhadamente sendo explicado aqui:
http://pt.wingwit.com/P/php-mysql-programming/92467.html#.VecgXsvlv5w
Citação:... Digite o comando [Ô] INSERT INTO nome_tabela ( col1, col2, Col3 ) VALUES ( col1_a , col2_a , col3_a ) , ( col1_b , col2_b , col3_b ) , ( col1_c , col2_c , col3_c ); [Ô]para inserir três linhas de registros na tabela ...
[][ô]s,
Tunusat.
Como já disse, você deveria usar OOP, carregar List<T> dos objetos coletados no excel, abastecer o grid e fazer qualquer modificação que queira nesses dados. Em seguida ao gravar, refaça o cast de gridview para List<T> que vai ter uma função genérica para formular o texto SQL, de preferência usando um StringBuilder ao invés de um string normal, dado o tamanho da massa de dados. O que é necessário entender é que o que você vê no grid, não são dados, mas a mera representação de objetos de dados, por isso não se deve usá-lo como tal.
Trabalhei a vida toda com VB6. Fiquei viciado em determinados procedimentos e agora estou com enorme dificuldade em me adptar no VB.Net e no ASP.net. Deixa ver se entendi mas provavelmente, não.
Me conecto com o arquivo excel e retiro os dados usando um DataTable.
Jogo esses dados em um DataGrid e por não saber como alterar diretamente no DataTable, faço as alterações no DataGrid.
Ai vc diz [Ô]Em seguida ao gravar, refaça o cast de gridview para List<T>[Ô]. Me perdoe a inexperiência mas porque eu iria carregar um List com os dados alterados do DataGrid para depois salvar no BD sendo que eu poderia já ir salvando á medida que eu for carregando essas linhas. Isso não é desnecessário e não vai atrasar mais?
Outra dúvida. Imaginando que meu DataGrid (DgExcel) tenha apenas 3 colunas, vou criar um loop para correr linha por linha até chegar ao final e montar o comando sugerido:
Com certeza meu raciocÃnio está errado pois esse comando acima não faz sentido nenhum.
Me conecto com o arquivo excel e retiro os dados usando um DataTable.
Jogo esses dados em um DataGrid e por não saber como alterar diretamente no DataTable, faço as alterações no DataGrid.
Ai vc diz [Ô]Em seguida ao gravar, refaça o cast de gridview para List<T>[Ô]. Me perdoe a inexperiência mas porque eu iria carregar um List com os dados alterados do DataGrid para depois salvar no BD sendo que eu poderia já ir salvando á medida que eu for carregando essas linhas. Isso não é desnecessário e não vai atrasar mais?
Outra dúvida. Imaginando que meu DataGrid (DgExcel) tenha apenas 3 colunas, vou criar um loop para correr linha por linha até chegar ao final e montar o comando sugerido:
INSERT INTO Tabela (a, b, c) VALUES (DgExcel.Item(Var1, idx).Value, DgExcel.Item(Var2, idx).Value, DgExcel.Item(Var3., idx).Value), (O que coloco aqui 4, O que coloco aqui 5, O que coloco aqui 6), (O que coloco aqui 7, O que coloco aqui 8, O que coloco aqui 9)
Com certeza meu raciocÃnio está errado pois esse comando acima não faz sentido nenhum.
Bom, pegando carona no que o KERPLUNK sugeriu, você pode também pegar o objeto List<T> que conteria a representação do seu grid e usar o método AddRange do EntityFramework. Seria algo assim :
Se o uso do EntityFramework for inviavél pra você, então você pode ainda usar o ADO.NET puro se aproveitando do método ExecuteNonQueryAsync retornando uma Task e dessa forma não bloqueia a tela.
Existe n maneiras de fazer isso, ainda você pode usar INotifyPropertyChanged vinculando isso a uma Observablecollection, você só precisa se libertar das formas antigas.
Usar o EntityFramework é a melhor escolha na minha opnião, uso massivamente e é pra mim a bala de prata.
Abraços
db.Produtos.AddRange(suaLista);
db.SaveChanges();
. Se o uso do EntityFramework for inviavél pra você, então você pode ainda usar o ADO.NET puro se aproveitando do método ExecuteNonQueryAsync retornando uma Task e dessa forma não bloqueia a tela.
Existe n maneiras de fazer isso, ainda você pode usar INotifyPropertyChanged vinculando isso a uma Observablecollection, você só precisa se libertar das formas antigas.
Usar o EntityFramework é a melhor escolha na minha opnião, uso massivamente e é pra mim a bala de prata.
Abraços
Se o processo é:
Pegar Dados do Excel;
Carregar no DataGridView;
Alterar alguns dados;
Salvar num banco de dados MySQL;
O ideal seria:
Colocar os dados do Excel num DataTable;
Usar o DataTable como DataSource do DataGridView;
Vincular o DataTable com DataGridView, de modo que as modificações do usuário afetem seus registros do DataTable;
Iniciar uma transação no seu banco de dados;
Criar instruções Insert Into a cada N registros (conforme o colega acima falou) até que se acabem os registros do DataTable.
Finalizar transação
Caso não queria usar o DataTable, pode usar um List<T> como mencionado acima. Mas aà você teria que editar ele na unha (ao contrário do vÃnculo de DataSource do grid).
Além do mais, você precisa avaliar o que está fazendo sua aplicação ficar lenta. é percorrer o grid? São as instruções Insert? Não acredito que essas queries que tão fazendo ficar lento. Quer tirar a prova real? Ao invés de executar, grave elas num arquivo .txt. Depois execute o arquivo diretamente no MySQL e veja o tempo que vai demorar. A sintaxe em conjuntos de Insert Into e ele individual vai ter uma pequena diferença, mas nada muito gritante... até porque, o que vai mudar pro MySQL será só a primeira fase do interpretador do MySQL, depois na execução (que é o processo mais demorado na hora de realizar uma query) vai chegar tudo a mesma coisa.
Se o problema realmente for nas queries e estiver lento até na hora de importar pelo próprio MySQL, não tem muito o que fazer. Lembrando que vai ser um pouco mais lento na hora de importar o arquivo porque acessar a memória é muito mais rápido do que acessar um arquivo fÃsico né...
Boa sorte!
Pegar Dados do Excel;
Carregar no DataGridView;
Alterar alguns dados;
Salvar num banco de dados MySQL;
O ideal seria:
Colocar os dados do Excel num DataTable;
Usar o DataTable como DataSource do DataGridView;
Vincular o DataTable com DataGridView, de modo que as modificações do usuário afetem seus registros do DataTable;
Iniciar uma transação no seu banco de dados;
Criar instruções Insert Into a cada N registros (conforme o colega acima falou) até que se acabem os registros do DataTable.
Finalizar transação
Caso não queria usar o DataTable, pode usar um List<T> como mencionado acima. Mas aà você teria que editar ele na unha (ao contrário do vÃnculo de DataSource do grid).
Além do mais, você precisa avaliar o que está fazendo sua aplicação ficar lenta. é percorrer o grid? São as instruções Insert? Não acredito que essas queries que tão fazendo ficar lento. Quer tirar a prova real? Ao invés de executar, grave elas num arquivo .txt. Depois execute o arquivo diretamente no MySQL e veja o tempo que vai demorar. A sintaxe em conjuntos de Insert Into e ele individual vai ter uma pequena diferença, mas nada muito gritante... até porque, o que vai mudar pro MySQL será só a primeira fase do interpretador do MySQL, depois na execução (que é o processo mais demorado na hora de realizar uma query) vai chegar tudo a mesma coisa.
Se o problema realmente for nas queries e estiver lento até na hora de importar pelo próprio MySQL, não tem muito o que fazer. Lembrando que vai ser um pouco mais lento na hora de importar o arquivo porque acessar a memória é muito mais rápido do que acessar um arquivo fÃsico né...
Boa sorte!
vou ficar de olho pra acompanhar pq já tive vezes de criar aplicações atualizadas e ter q puxar dados de bases pre históricas, e foi demorado por manter um loop linha a linha no dataset q elaborei com os dados vindos dos antigos bancos....até entendi o sistema de passar varias linhas em um único select
vou acompanhar pra aprender uma forma mais pratica
vou acompanhar pra aprender uma forma mais pratica
Vou fazer alguns testes para ver onde está lento, conforme o DS2T sugeriu e testes também percorrendo um Data Table X DataGrid para ver os resultados.
Com relação á montar várias linhas em um único insert, seria isso??
Dessa forma estaria gravando 5 linhas de uma só vez?? é isso? A idéia do código acima tá correta???
Com relação á montar várias linhas em um único insert, seria isso??
INSERT INTO Tabela (a, b, c) VALUES
(DgExcel.Item(Var1, idx).Value, DgExcel.Item(Var2, idx).Value, DgExcel.Item(Var3., idx).Value),
(DgExcel.Item(Var1, idx + 1).Value, DgExcel.Item(Var2, idx + 1).Value, DgExcel.Item(Var3., idx + 1).Value),
(DgExcel.Item(Var1, idx + 2).Value, DgExcel.Item(Var2, idx + 2).Value, DgExcel.Item(Var3., idx + 2).Value),
(DgExcel.Item(Var1, idx + 3).Value, DgExcel.Item(Var2, idx + 3).Value, DgExcel.Item(Var3., idx + 3).Value),
(DgExcel.Item(Var1, idx + 4).Value, DgExcel.Item(Var2, idx + 4).Value, DgExcel.Item(Var3., idx + 4).Value)
Dessa forma estaria gravando 5 linhas de uma só vez?? é isso? A idéia do código acima tá correta???
Sim, sintaticamente está correto, cinco linhas serão inseridas, mas note que ao percorrer um grid, ou objeto gráfico utilizando algum loop, você estará automaticamente acionando toda a parte gráfica dele também, isso significa menor performance, isso se seu grid não possuir eventos com algum tratamento, que podem também serem acionados, ocasionando ainda menor performance e possivelmente causando algum problema.
Lembre-se também de colocar o nome correto da sua tabela e também das colunas no seu comando SQL
Lembre-se também de colocar o nome correto da sua tabela e também das colunas no seu comando SQL
Tópico encerrado , respostas não são mais permitidas