Página 1 de 1

UPDATE de vários registros

Enviado: 14 Jul 2021 07:11
por gilbertosilverio
Olá amigos,

Tenho uma duvida, se e possível fazer o UPDATE de vários registros de uma única vez?

Tenho uma base de 23000 registros, hoje faço a alteração item a item, so que demora um pouco, tem como executar o update de vários registros ao mesmo tempo...

Hoje faço desta maneira, item a item, queria fazer um único arquivo e atualizar tudo de uma só fez, e possível?

Código: Selecionar todos


              cQuery2   := [UPDATE agille54_api.tray_produtos ]
              cQuery2   += [SET estoque = ] + ALLTRIM(STR(nQTDE,11))+[, ]
              cQuery2   += [preco = ]       + ALLTRIM(nPRECO)       +[, ]
              IF xCod_Spec <> [nao]
                 cQuery2+= [894687_processamentoPendente = 'Atualizar', ]
              ENDIF
              cQuery2   += [845890_processamentoPendente = 'Atualizar' ]
              cQuery2   += [WHERE  sku = ]  + ALLTRIM(STR(MATA_GERAL[G,1],11))
              oQuery2   := oServer:Execute(cQuery2)

Grato.

UPDATE de vários registros

Enviado: 14 Jul 2021 09:42
por alxsts
Olá!
gilbertosilverio escreveu:Tenho uma duvida, se e possível fazer o UPDATE de vários registros de uma única vez?
Claro!

SQL foi pensado para trabalhar com conjuntos de registros. Fazer com que ele trabalhe linha a linha geralmente causa queda na performance.

No teu código, você atualiza colunas de uma tabela com o conteúdo de variáveis. Para conseguir o que quer, provavelmente os valores a atualizar precisarão estar em outra tabela. As duas tabelas precisarão ter uma coluna em comum que permita associar as duas tabelas, através da cláusula JOIN.

Veja alguns exemplos do comando UPDATE: =How to Update a Column Based on a Filter of Another Column (em inglês).

UPDATE de vários registros

Enviado: 14 Jul 2021 10:22
por gilbertosilverio
Alexandre,

Obrigado pela resposta.

Ate entendi a logica, só que não consegui executa-la no Heid, você poderia 'DESENHAR' pra mim, por que não vai mesmo... kkkk

Ja pesquisei, li muito, mais sem UM DESENHO(exemplo simples), não consigo fazer


Grato.

UPDATE de vários registros

Enviado: 14 Jul 2021 10:49
por alxsts
Olá!
STR(nQTDE,11)
ALLTRIM(nPRECO)
ALLTRIM(STR(MATA_GERAL[G,1],11))
Fica difícil "desenhar". Não sei de onde vem estes valores. Parece que você está percorrendo o array MATA_GERAL e atualizando a tabela.
Neste caso, teria que ser um a um mesmo. O UPDATE em massa se aplica a duas ou mais tabelas (vai pegar valores de uma e atualizar a segunda). No teu caso, só vejo uma tabela e os valores vem de variáveis de memória...
gilbertosilverio escreveu:so que demora um pouco,... [WHERE sku = ] + ALLTRIM(STR(MATA_GERAL[G,1],11)
Verifique na tua tabela se a coluna SKU tem índice. Se não tiver, crie um. 23000 registros é pouca coisa mas se não tiver índice, a cada UPDATE o SGBD vai ter que ler a tabela sequencialmente até encontrar o SKU desejado.

Para criar o índice, use o HaidiSQL.

Código: Selecionar todos

CREATE INDEX idx_sku ON agille54_api.tray_produtos (sku);

UPDATE de vários registros

Enviado: 14 Jul 2021 11:16
por gilbertosilverio
Alexandre,

E isso mesmo, uso uma matriz por que pego valores de 5 filiais em DBF, e tenho que subir para o site estes valores.

Estava pensando em criar uma tabela no sql, INSERIR esses valores e ai mesclar com a que preciso subir.

Mais ai e minha duvida, como ficaria esse update?

tabela.temp = sku, qtde, preco

agille54.tray = sku, qtde, preco

Como ALTERAR os valores? eis a questão... kkkk

Por favor pode me dar um ideia de como seria.

Grato.

UPDATE de vários registros

Enviado: 14 Jul 2021 11:59
por alxsts
Olá!

Supondo que as duas tabela tenham o mesmo layout:
sku
qtde
preco
atualizar ( 'SIM' ou 'NAO' )

tente assim:

Código: Selecionar todos

UPDATE agille54.tray t1 
INNER JOIN temp t2 
        ON (t1.sku = t2.sku)  
SET t1.qtde = t2.qtde, 
    t1.preco = t2.preco,
    t1.ATUALIZAR = CASE WHEN t2.atualizar = 'SIM' THEN 'ATUALIZAR' ELSE 'NAO ATUALIZAR' END;
Outra forma:

Código: Selecionar todos

UPDATE agille54.tray t1, temp t2
SET t1.qtde = t2.qtde, 
    t1.preco = t2.preco,
    t1.ATUALIZAR = CASE WHEN t2.atualizar = 'SIM' THEN 'ATUALIZAR' ELSE 'NAO ATUALIZAR' END;
WHERE t1.sku = t2.sku;

UPDATE de vários registros

Enviado: 14 Jul 2021 12:05
por JoséQuintas
gilbertosilverio escreveu:Estava pensando em criar uma tabela no sql, INSERIR esses valores e ai mesclar com a que preciso subir.
Mais ai e minha duvida, como ficaria esse update?
Sem complicar, eu faria assim:

Código: Selecionar todos

UPDATE .... AS A
INNER JOIN ( montagem da lista ) AS B ON A.CODIGO = B.CODIGO
SET A.SALDO = B.SALDO
Já tem exemplos aqui de como criar a lista.

UPDATE de vários registros

Enviado: 14 Jul 2021 12:31
por gilbertosilverio
Alexandre, Quintas,

Muito obrigado, agora consegui enxergar...

Valeu...

UPDATE de vários registros

Enviado: 14 Jul 2021 13:07
por gilbertosilverio
Olá Amigos,

Funcionou perfeitamente, um semana batendo cabeça, resolvido em segundos...

Criei um DBF temporário e subi os valores com uma rotina postada aqui do Quintas, onde ele INSERE dados de um DBF para o SQL, levou em media 16 segundos para subir os valores.

Código: Selecionar todos

...
   SELECT 0
   USE ( cTable ) ALIAS DbfDb

   cComplete :=DbfDb->(LASTREC())

   cSqlFix := "INSERT INTO " + cNewTable + " ( "
   FOR nCont = 1 TO FCount()
      cSqlFix += FieldName( nCont )
      IF nCont != FCount()
         cSqlFix += ", "
      ENDIF
   NEXT
   cSqlFix += " ) VALUES "
   cTxt := ""
Usei a rotina postada pelo Alexandre.

Código: Selecionar todos

UPDATE tray_produtos t1, tray_produtos_dbf t2
	SET t1.estoque = t2.estoque,
        t1.preco = t2.preco,
        t1.845890_processamentoPendente = t2.845890_processamentoPendente
	WHERE t1.sku = t2.sku AND t2.845890_processamentoPendente = 'ATUALIZAR' 
Pronto, tudo atualizado...

Novamente, Alexandre, Quintas, muito obrigado pela ajuda.

ps: Como dizia Chacrinha, neste mundo nada se cria tudo se copia... kkkkkk

UPDATE de vários registros

Enviado: 14 Jul 2021 15:12
por JoséQuintas
Ao invés disso, faz do jeito que comentei, não precisa arquivo temporário.

Código: Selecionar todos

USE (arquivoDBF) ALIAS temp
cLista := "SELECT " + Ltrim(Str(temp->Codigo)) + " AS CODIGO, " + Ltrim(Str( temp->Valor,16,2)) + " AS VALOR "
SKIP
DO WHILE ! Eof()
   cLista += " UNION ALL SELECT " + Ltrim(Str(temp->Codigo)) + ", " + Ltrim(Str( temp->Valor,16,2))
   SKIP
ENDDO
cSQL := "UPDATE tabela AS A" + ;
   " INNER JOIN (  "  + cLista + " ) AS B"
   " SET A.VALOR = B.VALOR"
cn:Execute( cSQL )
Assim a tabela é criada no próprio comando.

Mas esqueci de um detalhe: tem limite no comando, acho que é 4MB pra funcionar pelo terminal.

UPDATE de vários registros

Enviado: 14 Jul 2021 16:52
por alxsts
Olá!

Independentemente da solução que adotar, penso que o índice que mencionei acima é importante.