Usina BRAdvPL Guia
Entrar
← Todos os tópicos
FUNDAMENTOPublicado

Campo D_E_L_E_T_ e exclusão lógica no Protheus

D_E_L_E_T_ = espaço → registro ativo | D_E_L_E_T_ = "*" → registro excluído logicamente

Entenda 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.

Banco de dadosSQLDBAccessTopConnExclusão lógicaD_E_L_E_T_
01 · VISÃO GERAL

Visão geral

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.

02 · SINTAXE

Sintaxe

D_E_L_E_T_ = espaço → registro ativo | D_E_L_E_T_ = "*" → registro excluído logicamente

Parâmetros

D_E_L_E_T_
Campo de controleObrigatório

Flag de exclusão lógica. Espaço em branco indica registro ativo; asterisco indica registro excluído logicamente.

R_E_C_N_O_
Campo de controleOpcional

Identificador físico usado como referência de posicionamento e compatibilidade com Recno() em ambiente SQL.

R_E_C_D_E_L_
Campo de controleOpcional

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.

Retorno

Não é uma função; é uma convenção de persistência das tabelas Protheus em banco relacional.

03 · EXEMPLO PRÁTICO

Consulta simples considerando apenas registros ativos

#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())
Return
Resultado esperado

A query retorna somente clientes ativos da filial correta e fecha a área temporária ao final.

04 · EXEMPLO PRÁTICO

JOIN filtrando exclusão lógica em cada tabela

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_ = ' ' "
Resultado esperado

O filtro aparece tanto na SA1 quanto na SE1. Assim a junção não mistura registros ativos com registros excluídos logicamente.

05 · EXEMPLO PRÁTICO

R_E_C_D_E_L_ e reutilização de chave

// Conceito simplificado:
// CODIGO  R_E_C_N_O_  D_E_L_E_T_  R_E_C_D_E_L_
// 001     1           "*"          1
// 001     2           " "          0
Resultado esperado

O 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.

BOAS PRÁTICAS
  • Inclua o filtro de exclusão lógica em toda tabela Protheus consultada diretamente por SQL.
  • Quando usar alias na query, qualifique o campo: SA1.D_E_L_E_T_ = ' ', SB1.D_E_L_E_T_ = ' ' e assim por diante.
  • Em JOINs, aplique o filtro da tabela associada no local coerente com o tipo de JOIN para não alterar o resultado esperado.
  • Use RetSqlName() para obter o nome físico da tabela e ChangeQuery() para compatibilizar a instrução com bancos homologados.
  • Exclusão lógica não é exclusão física. A eliminação física depende de rotinas próprias, como PACK em contexto AdvPL ou operações SQL cuidadosamente governadas.
  • Em rotinas de alteração ou exclusão, prefira os mecanismos do Protheus/DBAccess e respeite transações, bloqueios, dicionário e regras de negócio.
ARMADILHAS COMUNS
  • Esquecer D_E_L_E_T_ em uma query pode trazer registros que o Protheus considera excluídos.
  • Filtrar D_E_L_E_T_ apenas na tabela principal não basta quando há JOIN com outras tabelas Protheus.
  • Usar DELETE físico diretamente no banco pode quebrar rastreabilidade, integridade operacional, auditoria e expectativas das rotinas padrão.
  • Não atualize manualmente D_E_L_E_T_, R_E_C_N_O_ ou R_E_C_D_E_L_ sem domínio técnico, homologação e plano de reversão.
  • Não deduza o nome físico da tabela pelo sufixo; ambientes com grupos de empresas e compartilhamento exigem RetSqlName().

Conteúdos relacionados

REFERÊNCIAS
  1. MICROSIGA. Programação ADVPL — Utilização de Query. Documento Programação ADVPL X SQL, arquivo fornecido ao projeto, 27 ago. 2006. Seção "Particularidades Protheus".
  2. TOTVS. Cross Segmento - TOTVS Backoffice Linha Protheus - ADVPL - Comandos DML em SQL/DBAccess. Central de Atendimento TOTVS.
  3. TOTVS. Desenvolvendo queries no Protheus. TDN.
  4. TOTVS. Comando TCQUERY. TDN.
Situação
Publicado
Página criada em
Última revisão em
Idioma original
Português
Revisão
Usina.BR
0 comentário(s) aprovado(s)

Comentários

Ainda não há comentários aprovados.

Entre com Google ou Microsoft para comentar.

Powered by Usina Docs · Alpha