Como fazer um update via AdvPL

Hoje pessoal, vou mostrar como usar a função TCSQLExec para executar um update via AdvPL.

Antes de começarmos, ressalto que todas as operações de manipulação de dados (inserção, alteração e exclusão), devem ser feitas usando as próprias telas do ERP ou por meio de execução automática (ExecAuto). Nós explicamos mais sobre isso, nesse artigo – Por qual motivo não podemos dar DELETE ou INSERT diretamente em uma tabela do Protheus.

E se realmente precisar manipular, que seja em tabelas customizadas para não impactar no funcionamento do sistema.

Opcionalmente, precisamos iniciar o controle de transações, com Begin Transaction / End Transaction.

Então, montamos uma query de atualização em uma variável caractere, como por exemplo, cQryUpd.

Depois, executamos essa query com TCSQLExec, e se houve algum erro, nós desarmamos a transação.

Abaixo o exemplo:

Begin Transaction
    cNovoStatus := "A"
    cCodigo := "000111"
     
    //Monta o Update
    cQryUpd := " UPDATE " + RetSqlName("Z39") + " "
    cQryUpd += "     SET Z39_STATUS = '" + cNovoStatus + "' "
    cQryUpd += " WHERE "
    cQryUpd += "     Z39_FILIAL = '" + FWxFilial('Z39') + "' "
    cQryUpd += "     AND Z39_CODIGO = '" + cCodigo + "' "
    cQryUpd += "     AND D_E_L_E_T_ = ' ' "
 
    //Tenta executar o update
    nErro := TcSqlExec(cQryUpd)
     
    //Se houve erro, mostra a mensagem e cancela a transação
    If nErro != 0
        MsgStop("Erro na execução da query: "+TcSqlError(), "Atenção")
        DisarmTransaction()
    EndIf
End Transaction

Update 2023:

Pensando em facilitar mais o dia a dia de quem às vezes tem que executar atualizações via AdvPL, construímos uma função chamada zExecQry, onde basta você acioná-la passando a query, que ela já faz a execução para você. Abaixo o código fonte.

//Bibliotecas
#Include "TOTVS.ch"
#Include "TopConn.ch"

/*/{Protheus.doc} User Function zExecQry
Função que executa uma query e já exibe um log em tela em caso de falha
@type  Function
@author Atilio
@since 27/01/2023
@param cQuery, Caractere, Query SQL que será executada no banco
@param lFinal, Lógico, Define se irá encerrar o sistema em caso de falha
@return lDeuCerto, Lógico, .T. se a query foi executada com sucesso ou .F. se não
@example
    u_zExecQry("UPDATE TABELA SET CAMPO = 'AAAA'")
/*/

User Function zExecQry(cQuery, lFinal)
    Local aArea     := FWGetArea()
    Local lDeuCerto := .F.
    Local cMensagem := ""
    Default cQuery  := ""
    Default lFinal  := .F.

    //Executa a clausula SQL
	If TCSqlExec(cQuery) < 0
        
        //Caso não esteja rodando via job / ws, monta a mensagem e exibe
        If ! IsBlind()
            cMensagem := "Falha na atualização do Banco de Dados!" + CRLF + CRLF
            cMensagem += "/* ==== Query: ===== */" + CRLF
            cMensagem += cQuery + CRLF + CRLF
            cMensagem += "/* ==== Mensagem: ===== */" + CRLF
            cMensagem += TCSQLError()
            ShowLog(cMensagem)
        EndIf

        //Se for para abortar o sistema, será exibido uma mensagem
        If lFinal
		    Final("zExecQry: Falha na operação. Contate o Administrador.")
        EndIf

    //Se deu tudo certo, altera a flag de retorno
    Else
        lDeuCerto := .T.
	EndIf

    FWRestArea(aArea)    
Return lDeuCerto

Bom pessoal, por hoje é só.

Abraços e até a próxima.

Dan (Daniel Atilio)
Cristão de ramificação protestante. Especialista em Engenharia de Software pela FIB, graduado em Banco de Dados pela FATEC Bauru e técnico em informática pelo CTI da Unesp. Entusiasta de soluções Open Source e blogueiro nas horas vagas. Autor e mantenedor do portal Terminal de Informação.

6 Responses

  1. Caio disse:

    No Lugar das variáveis:

    cNovoStatus := “A”
    cCodigo := “000111”

    Tem como posicionar um registro preenchido por um usuário em uma pergunta customizada criada na SX1 ?

    • Bom dia Caio, tudo joia?

      Sim, você pode customizar, colocando parâmetros de um Pergunte (SX1) ou de um ParamBox (array).

      Logo após você colocar o seu Pergunte(), na montagem da sua query, na string, você substitui pelo parâmetro informado.

      Por exemplo, supondo então que o código seja o parâmetro de número 1 e o status de número 2, nas suas variáveis antes da montagem da query, ficaria algo assim por exemplo:
      cNovoStatus := MV_PAR02
      cCodigo := MV_PAR01

      Tenha uma ótima e abençoada terça feira.

      Um grande abraço.

  2. Olá Daniel tudo bem ?

    como foi quebrado em duas partes o código como ficaria o mesmo inteiro ? sendo que não estou entender claramente se eu preciso colocar o begin transaction.

    desde já agradeço , sou seu fan !

Deixe uma resposta

Terminal de Informação