ClipaTec Informática

Receba novidades por e-mail. Digite seu e-mail abaixo e clique no botão "Cadastrar"

Delivered by FeedBurner

11 de agosto de 2017

Comando Array DML (FireDAC) no Delphi

array dml firedac delphi

Olá clipatequeiros. Espero que esteja tudo bem com vocês.
Já imaginou mais de dez mil registros sendo sincronizados em poucos segundos? Parece utópico não? Pois bem, utilizando o Delphi com FireDAC, veremos como isso é possível, mesmo fora da rede local, por exemplo, cadastrar registros em um banco de dados que esteja em um servidor nas nuvens.
Bom, se você ainda está lendo este artigo, é porque certamente você está curioso para entender como isso pode ser feito certo? A mágica toda se dá através do comando ArrayDML, mas, que diabos é "Array DML"?
OK, vamos em frente. Sucintamente explicando, o ArrayDML é um comando que nos proporciona a execução em lote de instruções SQL de maneira muito rápida. É um recurso provido pelo FireDac.
O objetivo deste artigo é mostrar a performance deste comando, mesmo executando a inserção de milhares de registros por segundo e tudo isso utilizando apenas algumas linhas de código. Vou lhe mostrar o modelo convencional adotado pela maioria hoje, e o novo modelo usando Array DML.
O Array DML ainda não é muito popular, visto que a maioria ainda não o conhece. Mas vamos pensar em um caso de uso. Imagine que você precisa transferir dados de um determinado banco para outro. Normalmente, você faria um laço de repetição, onde para cada registro do banco A percorrido, o mesmo seria cadastrado no banco B. Teríamos uma estrutura assim (convencional):

procedure TFrmCadastro.InserirItens;
var
  sComandoSQL: string;
begin
  sComandoSQL := 'insert into venda_iten values(:id_produto, :qtd, :preco)';

  cdsItens.Open;
  cdsItens.First;
  while not cdsItens.Eof do
  begin
    sqlCad.CommandText           := EmptyStr;
    sqlCad.CommandText           := sComandoSQL;
    sqlCad.Params[0].AsInteger  := cdsItensID_PRODUTO.AsInteger;
    sqlCad.Params[1].AsFloat     := cdsItensQTD.AsFloat;
    sqlCad.Params[2].AsFloat     := cdsItensPRECO.AsFloat;
    sqlCad.ExecSQL;

    cdsItens.Next;
  end;
  cdsItens.Close;
  sqlCad.Close;
end;


Esse modelo convencional, é muito mais lento, visto que, para cada registro um comando insert neste caso é realizado, desta forma, cada registro é na verdade uma solicitação que é enviada para o banco, pensando numa estrutura cliente/servidor onde o banco fica em um computador separado, isso torna o trafego na rede muito mais pesado, e o tempo de ida (instrução SQL) e vinda (retorno) fica muito mais lento. Com o Array DML, conseguimos enviar um conjunto de dados dentro de uma mesma transferência, e o ganho que temos em performance, é assustadoramente incrível.
Vale ressaltar que não necessariamente seja instruções de insert, pode ser update, delete ou qualquer outro comando parametrizado.
Agora, vamos ver como isso ficaria usando o ArrayDML. Observe a estrutura:

procedure TFrmCadastro.InserirItens;
var
  sComandoSQL: string;
  iNumInserts: Integer;
begin
  sComandoSQL := 'insert into venda_iten values(:id_produto, :qtd, :preco)';

  fdqItens.Open;
  fdqItens.Last;

  iNumInserts := fdqItens.RecordCount;

  fdqCad.Active := False;
  fdqCad.SQL.Add(sComandoSQL);

  fdqCad.Params.ArraySize := iNumInserts;

  fdqItens.First;
  fdqItens.DisableControls;
  while not fdqItens.Eof do
  begin
    fdqCad.Params[0].AsIntegers[fdqItens.RecNo-1] :=
      fdqItens.ID_PRODUTO.AsInteger;
    fdqCad.Params[1].AsFloats[fdqItens.RecNo-1] :=  fdqItensQTD.AsFloat;
    fdqCad.Params[2].AsFloats[fdqItens.RecNo-1] := fdqItensPRECO.Float;
 
    fdqItens.Next;
  end;

  if intNumInserts > 0 then
     fdqCad.Execute(iNumInserts, 0);

  fdqCad.Active := False;
end;


Muito bem, se observar no código acima, criamos uma variável "iNumInserts" onde armazenaremos a quantidade de instruções SQL a serem executadas, depois definimos um array no FDQuery de cadastro com o tamanho de instruções.
No laço While apenas alimentamos as posições do array com as instruções SQL, e fora do laço, nós executamos todas estas instruções.
Galera, podem cronometrar o modelo convencional e o modelo usando ArrayDML com a mesma quantidade de registros, e vejam vocês mesmo a diferença de tempo. É lindo 😄
Teste ai e comentem, em caso de dúvida, deixe seu comentário.
Um grade abraço e até o próximo.

(By ClipaTec Informática)

0 comentários:

Postar um comentário

Visite nossa página de Política de comentarios antes de comentar para ter certeza de que seu comentário não será excluído! Lembre-se, assim que aprovarmos o teu comentário ele será publicado, por isso, não deixe de sempre visitar nosso blog e conferir nossa resposta ao seu comentário, abraço!