SALVAR DADOS EM MYSQL

MLALEX 01/09/2015 20:20:00
#450842
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??
KERPLUNK 01/09/2015 20:26:21
#450844
Resposta escolhida
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:

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.
MLALEX 02/09/2015 11:27:21
#450877
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???
TUNUSAT 02/09/2015 13:16:09
#450888
MLALEX,

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.
KERPLUNK 02/09/2015 19:37:00
#450910
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.
MLALEX 02/09/2015 20:44:09
#450918
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:

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.


LAMPIAO 02/09/2015 20:48:32
#450919
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 :

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
DS2T 02/09/2015 20:49:07
#450920
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!

NICKOSOFT 03/09/2015 08:25:11
#450936
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
MLALEX 03/09/2015 16:36:39
#450968
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??

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???
KERPLUNK 03/09/2015 17:00:33
#450969
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
Página 1 de 2 [12 registro(s)]
Tópico encerrado , respostas não são mais permitidas