D_E_L_E_T_Flag de exclusão lógica. Espaço em branco indica registro ativo; asterisco indica registro excluído logicamente.
AdvPL GuiaD_E_L_E_T_ = espaço → registro ativo | D_E_L_E_T_ = "*" → registro excluído logicamenteEntenda como o Protheus representa exclusão lógica no banco SQL e por que consultas devem filtrar D_E_L_E_T_ em cada tabela.
No Protheus, a exclusão padrão de registros é lógica: o registro permanece fisicamente na tabela, mas o campo D_E_L_E_T_ passa a indicar que ele não deve mais ser considerado pela aplicação. Em consultas SQL, isso exige atenção especial, porque o banco continua retornando linhas excluídas se a query não filtrar esse campo. O material histórico Programação ADVPL X SQL também relaciona D_E_L_E_T_ aos campos R_E_C_N_O_ e R_E_C_D_E_L_, usados pelo DBAccess para preservar compatibilidade com o modelo ISAM e permitir chaves únicas mesmo após exclusões lógicas.
D_E_L_E_T_ = espaço → registro ativo | D_E_L_E_T_ = "*" → registro excluído logicamenteD_E_L_E_T_Flag de exclusão lógica. Espaço em branco indica registro ativo; asterisco indica registro excluído logicamente.
R_E_C_N_O_Identificador físico usado como referência de posicionamento e compatibilidade com Recno() em ambiente SQL.
R_E_C_D_E_L_Auxilia a composição de chaves únicas em registros excluídos logicamente, recebendo o valor de R_E_C_N_O_ quando ocorre a exclusão.
Não é uma função; é uma convenção de persistência das tabelas Protheus em banco relacional.
#Include "TOTVS.ch"
#Include "TopConn.ch"
User Function ExDelLogico()
Local cAlias := GetNextAlias()
Local cQuery := ""
cQuery := "SELECT SA1.A1_COD, SA1.A1_LOJA, SA1.A1_NOME "
cQuery += "FROM " + RetSqlName("SA1") + " SA1 "
cQuery += "WHERE SA1.A1_FILIAL = '" + xFilial("SA1") + "' "
cQuery += "AND SA1.D_E_L_E_T_ = ' ' "
cQuery += "ORDER BY SA1.A1_COD, SA1.A1_LOJA"
cQuery := ChangeQuery(cQuery)
TCQUERY (cQuery) ALIAS (cAlias) NEW
While !(cAlias)->(Eof())
ConOut((cAlias)->A1_COD + " - " + (cAlias)->A1_NOME)
(cAlias)->(DbSkip())
EndDo
(cAlias)->(DbCloseArea())
ReturnA query retorna somente clientes ativos da filial correta e fecha a área temporária ao final.
cQuery := "SELECT SA1.A1_COD, SA1.A1_NOME, SE1.E1_NUM, SE1.E1_SALDO "
cQuery += "FROM " + RetSqlName("SA1") + " SA1 "
cQuery += "INNER JOIN " + RetSqlName("SE1") + " SE1 "
cQuery += "ON SE1.E1_FILIAL = '" + xFilial("SE1") + "' "
cQuery += "AND SE1.E1_CLIENTE = SA1.A1_COD "
cQuery += "AND SE1.E1_LOJA = SA1.A1_LOJA "
cQuery += "AND SE1.D_E_L_E_T_ = ' ' "
cQuery += "WHERE SA1.A1_FILIAL = '" + xFilial("SA1") + "' "
cQuery += "AND SA1.D_E_L_E_T_ = ' ' "O filtro aparece tanto na SA1 quanto na SE1. Assim a junção não mistura registros ativos com registros excluídos logicamente.
// Conceito simplificado:
// CODIGO R_E_C_N_O_ D_E_L_E_T_ R_E_C_D_E_L_
// 001 1 "*" 1
// 001 2 " " 0O registro excluído logicamente permanece na tabela, mas R_E_C_D_E_L_ ajuda a liberar a chave única para uma nova inclusão ativa.
© 2026 Usina.BR. Todos os direitos reservados. TOTVS, Protheus, Microsiga e seus respectivos logotipos são marcas de seus titulares. O AdvPL Guia é independente e utiliza citações limitadas, atribuídas e justificadas por finalidade educativa. Consulte os Termos de Uso. Termos de Uso
Comentários
Ainda não há comentários aprovados.
Entre com Google ou Microsoft para comentar.