Ariston Santos Posted May 16, 2014 Report Share Posted May 16, 2014 Olá, pessoal. Tenho duas tabelas de estoque, uma local em DBF e outra em um servidor remoto em MySQL. Preciso periodicamente atualizar o campo ESTOQUEATUAL na tabela remota a partir do DBF local. Ja tentei assim mas não funcinou: UPDATE ITENS_DB SET ESTOQUEATUAL = 0.000 WHERE CODIGO = '0001', SET ESTOQUEATUAL = 7.000 WHERE CODIGO = '0002', SET ESTOQUEATUAL = 2.000 WHERE CODIGO = '0003', SET ESTOQUEATUAL = 5.000 WHERE CODIGO = '0004' Assim também não vai: UPDATE ITENS_DB SET ESTOQUEATUAL = 0.000 WHERE CODIGO = '0001'; UPDATE ITENS_DB SET ESTOQUEATUAL = 7.000 WHERE CODIGO = '0002'; UPDATE ITENS_DB SET ESTOQUEATUAL = 2.000 WHERE CODIGO = '0003'; UPDATE ITENS_DB SET ESTOQUEATUAL = 5.000 WHERE CODIGO = '0004' Só funciona quando eu atualizo apenas um registro por vez, mas fica muito demorado. Preciso de um exemplo que faça a atualização de vários registros via query única. Tem como? Agradeço desde já. Quote Link to comment Share on other sites More sharing options...
emotta Posted May 16, 2014 Report Share Posted May 16, 2014 Airston, o segundo exemplo era pra funcionar. Como voce está executando e que erro esta retornando? Eu não conheço MYSQL mas primeiro faça funcionar o seu comando no equivalente ao QUERY ANALIZER do SQL SERVER. Fazendo funcionar o comando lá ai é só adaptar o codigo abaixo. Tente assim: cComando := "UPDATE ITENS_DB SET ESTOQUEATUAL = 0.000 WHERE CODIGO = '0001' "+Chr(13)+Chr(10)cComando += "UPDATE ITENS_DB SET ESTOQUEATUAL = 7.000 WHERE CODIGO = '0002' "+Chr(13)+Chr(10)cComando += "UPDATE ITENS_DB SET ESTOQUEATUAL = 2.000 WHERE CODIGO = '0003' "+Chr(13)+Chr(10)cComando += "UPDATE ITENS_DB SET ESTOQUEATUAL = 5.000 WHERE CODIGO = '0004' "+Chr(13)+Chr(10) SR_GetConnection():exec(cComando) SR_GetConnection():Commit() Olá, pessoal. Tenho duas tabelas de estoque, uma local em DBF e outra em um servidor remoto em MySQL. Preciso periodicamente atualizar o campo ESTOQUEATUAL na tabela remota a partir do DBF local. Ja tentei assim mas não funcinou: UPDATE ITENS_DB SET ESTOQUEATUAL = 0.000 WHERE CODIGO = '0001', SET ESTOQUEATUAL = 7.000 WHERE CODIGO = '0002', SET ESTOQUEATUAL = 2.000 WHERE CODIGO = '0003', SET ESTOQUEATUAL = 5.000 WHERE CODIGO = '0004' Assim também não vai: UPDATE ITENS_DB SET ESTOQUEATUAL = 0.000 WHERE CODIGO = '0001'; UPDATE ITENS_DB SET ESTOQUEATUAL = 7.000 WHERE CODIGO = '0002'; UPDATE ITENS_DB SET ESTOQUEATUAL = 2.000 WHERE CODIGO = '0003'; UPDATE ITENS_DB SET ESTOQUEATUAL = 5.000 WHERE CODIGO = '0004' Só funciona quando eu atualizo apenas um registro por vez, mas fica muito demorado. Preciso de um exemplo que faça a atualização de vários registros via query única. Tem como? Agradeço desde já. Quote Link to comment Share on other sites More sharing options...
leo@lhsistemas.com Posted May 16, 2014 Report Share Posted May 16, 2014 Ariston, boa tarde. Creio que seja assim: UPDATE ITENS_DB SET ESTOQUEATUAL = 0.000 WHERE CODIGO = '0001', ESTOQUEATUAL = 7.000 WHERE CODIGO = '0002', ESTOQUEATUAL = 2.000 WHERE CODIGO = '0003', ESTOQUEATUAL = 5.000 WHERE CODIGO = '0004' Abraços, Quote Link to comment Share on other sites More sharing options...
kleyber Posted May 16, 2014 Report Share Posted May 16, 2014 Ariston, A melhor forma de se fazer isso é criando um array com os registros que vão ser alterados. Assim você cria um único UPDATE. Não estou em casa, mas assim que chegar eu posso colar aqui um exemplo disto. Quote Link to comment Share on other sites More sharing options...
Ariston Santos Posted May 16, 2014 Author Report Share Posted May 16, 2014 Testei as sugestões acima mas ainda sem êxito. Kleyber, aguardo sua dica. Quote Link to comment Share on other sites More sharing options...
Wellington Vieira Posted May 17, 2014 Report Share Posted May 17, 2014 BEGIN; UPDATE ITENS_DB SET ESTOQUEATUAL = 0.000 WHERE CODIGO = '0001'; UPDATE ITENS_DB SET ESTOQUEATUAL = 7.000 WHERE CODIGO = '0002'; UPDATE ITENS_DB SET ESTOQUEATUAL = 2.000 WHERE CODIGO = '0003'; UPDATE ITENS_DB SET ESTOQUEATUAL = 5.000 WHERE CODIGO = '0004'; COMMIT; Quote Link to comment Share on other sites More sharing options...
kleyber Posted May 17, 2014 Report Share Posted May 17, 2014 Ariston, Segue a idéia // Aqui você começa o loop no teu dbf. No meu caso foi em um arquivo texto. if cSituaope="Crédito Enviado" cSitContrato:="AGUARDANDO LIBERAÇÃO PARA PAGAMENTO" elseif cSituaope="Cancelada" cSitContrato:="CANCELADA" else cSitContrato:="EM ANÁLISE" endif cCpf:=strtran(aReg[10],".","") cCpf:=strtran(cCpf,"-") aAdd(aDadosTXT,"("+Any2Sql( cCodLoja )+","+; Any2Sql( upper(alltrim(aReg[8])) )+","+; Any2Sql( alltrim(aReg[3]) )+","+; Any2Sql( aReg[37] )+","+; Any2Sql( alltrim(aReg[31]) )+","+; Any2Sql( alltrim(cNumope))+","+; Any2Sql( cMatFunc )+","+; Any2Sql( cFisico )+","+; if(empty(cNumope),"1","0")+","+; Any2Sql( aReg[7] )+","+; Any2Sql( date() )+","+; Any2Sql( cTipopag )+","+; Any2Sql( alltrim(cCpf) )+","+; Any2Sql( cTipoCorretor )+","+; Any2Sql( cSitContrato )+")") ... ... Depois do loop faço assim: if !empty(aDadosTXT) cSql:="INSERT INTO tab_prot (cod_loja,nome_cliente,cod_convenio,valor,ade,contrato,"+; "mat_func,fisico,cod_produto,usuario,dtcada,tipoconta,cpf,tipocorretor,statusconsig) VALUES " for nI:=1 to len(aDadosTXT) cSql+=aDadosTXT[nI]+"," next // Apagar última virgula cSql:=substr(cSql,1,len(cSql)-1) Begin Transaction SQL Execute cSql IF SQL_ErrorNO() > 0 SQLRollBack() End Transaction MsgInfo( "Informe esta mensagem ao suporte : "+CRLF+; SQLErrorMsg(),"ATENÇÃO" ) ENDIF End Transaction SQL EXECUTE "COMMIT" // Para gravar as atualzações no banco endif Lembrando que faço isto usando SQLLIB, mas a idéia é a mesma, ou seja, neste caso executo um único INSERT ou poderia ser um UPDATE com todas as linhas que preciso. Espero que sirva. Quote Link to comment Share on other sites More sharing options...
Ariston Santos Posted May 17, 2014 Author Report Share Posted May 17, 2014 kleyberObrigado, mas não serve. Para INSERT eu ja tenho uma rotina que está funcinando corretamente. Já consigo inserir quantos registros novos que quiser enviando apenas uma query para o BD. O que preciso para o momento é de um exemplo para UPDATE. O motivo é que são vários registros no banco de dados. Alterar um a um via internet fica muito lento. Por isso surgiu a idéia de enviar os itens por blocos de 100. Assim, em uma tabela com mil itens, eu enviaria dez queries com 100 itens cada uma. Até um momento não consegui isso usando a SQLRDD, comandos em sql puro. Optei por enviar um a um até que surja uma dica funcional. Por enquanto, obrigado a todos pelo esforço em ajudar. Quote Link to comment Share on other sites More sharing options...
miragerr Posted May 18, 2014 Report Share Posted May 18, 2014 Ola Boa noite Ariston, de onde vem estes "CODIGO = '0001'", isto é um sequencial, de onde voce pega este '0001'. Explique melhor o que você quer fazer. Fico no aguardo. Quote Link to comment Share on other sites More sharing options...
kleyber Posted May 18, 2014 Report Share Posted May 18, 2014 Ariston, Acho que você não entendeu. Basta mudar o INSERT por UPDATE que iria funcionar. Mas blz, de qualquer forma tentei algo. Quote Link to comment Share on other sites More sharing options...
Erciley Junior Posted May 19, 2014 Report Share Posted May 19, 2014 Ariston, pelo que sei, não dá para atualizar registros diferentes, aplicando informações diferentes em um mesmo campo, com condições diferentes ou seja, tem que atualizar "1 a 1" mesmo. O que torna esse tipo de atualização mais rápida, é abrir um TRANSACTION, para não ficar comitando a cada UPDATE realizado, isso dá uma GRAAANDE diferença dependendo a quantia de UPDATES enviados. Quote Link to comment Share on other sites More sharing options...
Ariston Santos Posted May 19, 2014 Author Report Share Posted May 19, 2014 Ariston, de onde vem estes "CODIGO = '0001'", isto é um sequencial, de onde voce pega este '0001'. Vem da tabela ITENS_DB, campo CODIGO. Antes de fazer o update, eu pego os itens cadastrados na tabela online em um vetor (via SELECT). Atualizo o estoque no vetor com base no DBF local, e quero dar um UPDATE na tabela online de todos os itens do vetor. Acho que você não entendeu. Basta mudar o INSERT por UPDATE que iria funcionar. Mas blz, de qualquer forma tentei algo. Vou testar isso. Se funcionar, aviso. Ariston, pelo que sei, não dá para atualizar registros diferentes, aplicando informações diferentes em um mesmo campo, com condições diferentes, ou seja, tem que atualizar "1 a 1" mesmo. O que torna esse tipo de atualização mais rápida, é abrir um TRANSACTION, para não ficar comitando a cada UPDATE realizado, isso dá uma GRAAANDE diferença dependendo a quantia de UPDATES enviados. O Kleyber afima asima que apenas trocando o INSERT por UPDATE dá sim. De qualquer forma, já estou usando BEGIN e END TRANSCTION - SR_BeginTransaction() e SR_CommitTransaction(). Realmente fica bem mais rápido, mas ainda poderia melhorar. Obrigado a todos. Quote Link to comment Share on other sites More sharing options...
Erciley Junior Posted May 19, 2014 Report Share Posted May 19, 2014 Ariston, a única forma que enxergo para fazer isso com apenas um comando, seria como o exemplo abaixo. UPDATE ITENS_DB SET ESTOQUEATUAL = CASE CODIGO WHEN '0001' THEN 0.000 WHEN '0002' THEN 7.000 WHEN '0003' THEN 2.000 WHEN '0004' THEN 5.000 END WHERE CODIGO IN ('0001','0002','0003','0004'); Fazer isso em um LOOP é fácil, mas dependendo o número de dados, pode haver problemas no fivewin, com o tamanho da string ou pode haver problema no banco de dados, com o tamanho do pacote enviado, então seria bom que você tivesse um limite de códigos a atualizar de uma única vez, para não haver nenhum dos 2 problemas citados. Quote Link to comment Share on other sites More sharing options...
Jmsilva Posted May 19, 2014 Report Share Posted May 19, 2014 Ariston, sugiro vc faça uma pesquisa sobre como criar um "function no banco de dados", assim vc passa os dados como parâmetros para banco de dados em uma única chamada e internamente o banco faz a atualização (vários update), fica rápido e não consome banda. delimiter $$ create function upd_variosReg(p1 varchar,p2 varchar) returns bool BEGIN UPDATE ITENS_DB SET ESTOQUEATUAL = 0.000 WHERE CODIGO = p1; UPDATE ITENS_DB SET ESTOQUEATUAL = 7.000 WHERE CODIGO = p2; UPDATE ITENS_DB SET ESTOQUEATUAL = 2.000 WHERE CODIGO = p3; UPDATE ITENS_DB SET ESTOQUEATUAL = 5.000 WHERE CODIGO = p4; return true; END $$ delimiter ; no seu prg func main cmdSql := "Call upd_variosReg("0001","002",....);" Ariston Santos 1 Quote Link to comment Share on other sites More sharing options...
Ariston Santos Posted May 19, 2014 Author Report Share Posted May 19, 2014 UPDATE ITENS_DB SET ESTOQUEATUAL = CASE CODIGO WHEN '0001' THEN 0.000 WHEN '0002' THEN 7.000 WHEN '0003' THEN 2.000 WHEN '0004' THEN 5.000 END WHERE CODIGO IN ('0001','0002','0003','0004'); Perfeito. Funcionou. Era exatamente isso que eu queria. ISSO É QUE FORUM!! Obrigado a todos. Quote Link to comment Share on other sites More sharing options...
emotta Posted May 19, 2014 Report Share Posted May 19, 2014 When em instrução sql eu não conhecia.... Vou ver se funciona também em SQL SERVER... Mais uma coisa aprendida... vlww Perfeito. Funcionou. Era exatamente isso que eu queria. ISSO É QUE FORUM!! Obrigado a todos. Quote Link to comment Share on other sites More sharing options...
Erciley Junior Posted May 19, 2014 Report Share Posted May 19, 2014 Oi Emotta, na verdade o WHEN é uma instrução do comando CASE. Daria pra fazer com IF´s, mas o código ficaria meio poluído ........ e funciona em SQL Server sim. ^^ Uma dica pra quem está em casa e não tem sql server, mysql, oracle instalado, é usar o sqlfiddle é um site que você pode simular uma base de dados em qualquer uma dessas linguagens, entre outras...... tem até um botãozinho Donate pra quem animar, hehehe http://sqlfiddle.com/ Quote Link to comment Share on other sites More sharing options...
emotta Posted May 19, 2014 Report Share Posted May 19, 2014 Fantastico... obrigado ! Oi Emotta, na verdade o WHEN é uma instrução do comando CASE. Daria pra fazer com IF´s, mas o código ficaria meio poluído ........ e funciona em SQL Server sim. ^^ Uma dica pra quem está em casa e não tem sql server, mysql, oracle instalado, é usar o sqlfiddle é um site que você pode simular uma base de dados em qualquer uma dessas linguagens, entre outras...... tem até um botãozinho Donate pra quem animar, hehehe http://sqlfiddle.com/ Quote Link to comment Share on other sites More sharing options...
Allan Cas Posted January 26, 2018 Report Share Posted January 26, 2018 Boa tarde Ariston Santos, estava com o mesmo problema e tentei utilizar o WHEN, porem não meu caso não funcionou, pois estava usando 15 digitos e estourou o limite do INT. Resolvi o caso da seguinte forma. UPDATE ITENS_DB SET ESTOQUEATUAL = 0.000 WHERE CODIGO = '0001'; UPDATE ITENS_DB SET ESTOQUEATUAL = 7.000 WHERE CODIGO = '0002'; UPDATE ITENS_DB SET ESTOQUEATUAL = 2.000 WHERE CODIGO = '0003'; UPDATE ITENS_DB SET ESTOQUEATUAL = 5.000 WHERE CODIGO = '0004'; Utilizando todos os pontos e virgulas no final (;) é exibido a mensagem de apenas 1 Update (apenas 1 comando), porem ao realizar o select, todos os registros foram atualizados. Testei no POSTGRE e funcionou, faça o teste por gentileza. Quote Link to comment Share on other sites More sharing options...
Ariston Santos Posted January 28, 2018 Author Report Share Posted January 28, 2018 Oi, amigo. Quem bom saber que este tópico, apesar de ser antigo, ainda está em alta (kkk). A ideia é interessante, mas como no meu caso nunca vai passar de 13 dígitos, vou preferir mantar como está, pois está funcionando bem. Grato! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.