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.
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.
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 !
Bom dia Leonardo, tudo joia graças a Deus e você?
Opa, primeiramente obrigado pelo comentário e pelo carinho, é muita bondade sua.
Não precisa usar o Begin Transaction, quanto ao exemplo, ao invés de acionar o TCSQLExec (no primeiro fonte), você acionaria direto a User Function, então ao invés disso:
nErro := TcSqlExec(cQryUpd)
Ficaria assim:
u_zExecQry(cQryUpd)
Pois o segundo trecho é uma função criada para encapsular e executar o udpate. Ai se quiser ver em exemplos mais aprimorados, segue dois links, ai dentro deles, procure por “zExecQry”:
https://terminaldeinformacao.com/2024/08/06/como-atualizar-um-browse-ao-alternar-de-linha-de-outro-browse-ti-responde-0070/
https://terminaldeinformacao.com/2024/01/03/como-criar-um-cadastro-em-mvc-de-uma-tabela-fora-do-dicionario-do-protheus/
Tenha um ótimo e abençoado fim de semana.
Um grande abraço.
Opa bom dia Mestre , muito obrigado me ajudou muito
Sou seu fan 😀
Bom dia Leonardo, tudo joia?
Nós que agradecemos pelo comentário e feedback.
É muita generosidade sua.
Tenha uma ótima e abençoada quinta feira.
Um grande abraço