[2C] Trigger Oracle/Protheus não captura delete lógico (D_E_L_E_T_) quando entidade possui SQL condicional
Description
Contexto
Identificamos um possível problema no 2C em ambiente Oracle + Protheus, quando uma entidade sincronizada por trigger possui SQL condicional configurado.
Cenário do cliente
-
2C versão 3.7.4
-
Banco Oracle 19.30
-
Conexão marcada como Protheus
-
ignoreTriggers=false
-
Entidade impactada: PHL000
-
Entidade com SQL condicional:
SUBSTR(PHL_CMPDIF, 4,4) || SUBSTR(PHL_CMPDIF, 1,2) >= '202307'
Problema observado
No Protheus, a exclusão lógica ocorre por UPDATE no campo D_E_L_E_T_, normalmente alterando o valor para *. Nesse caso, a trigger de UPDATE deveria inserir um registro na CAROL_3C_QUEUE com op_type = 1 para que a exclusão seja enviada à Carol.
Porém, a trigger Oracle/Protheus gerada para UPDATE contém uma cláusula WHEN restringindo a execução a registros ativos:
WHEN ((TRIM(n.D_E_L_E_T_) IS NULL) AND (...condicional da entidade...))
Dentro da própria trigger existe a lógica:
CASE WHEN TRIM(:n.D_E_L_E_T_) IS NULL THEN 0 ELSE 1 END
A intenção dessa lógica é mapear:
-
D_E_L_E_T_ vazio/nulo => op_type = 0
-
D_E_L_E_T_ preenchido => op_type = 1
Mas, como o WHEN exige TRIM(n.D_E_L_E_T_) IS NULL, quando o D_E_L_E_T_ passa para *, a trigger não executa. Assim, o caminho ELSE 1 fica inalcançável nesse cenário e a exclusão lógica não entra na fila.
Diferença observada em relação ao SQL Server
No SQL Server, o template da trigger de UPDATE Protheus calcula o op_type com base em D_E_L_E_T_, mas o gerador não injeta automaticamente uma condição equivalente a n.D_E_L_E_T_ IS NULL no filtro da trigger de update. Portanto, o problema específico do Oracle parece estar associado ao WHEN gerado para Oracle/Protheus com SQL condicional.
Evidências
-
Heartbeat do cliente confirma:
-
versão 2C: 3.7.4
-
banco: Oracle 19.30
-
conexão type=ORACLE
-
isProtheus=true
-
useProtheusCompanyCode=true
-
ignoreTriggers=false
-
entidade PHL000 com conditionalSql configurado
-
syncByFullLoad=false
-
syncByTimestamp=false
-
-
Healthcheck mostra as triggers insert/update/delete da PHL000 como OK, mas isso valida apenas existência/status da trigger, não a regra lógica do WHEN.
-
A fila pendente do heartbeat não mostra PHL000, compatível com o cenário em que o update de delete lógico não gerou entrada na CAROL_3C_QUEUE.
-
DDL da trigger de UPDATE enviada pelo cliente mostra:
-
WHEN ((TRIM(n.D_E_L_E_T_) IS NULL) AND (...)) -
CASE WHEN TRIM(:n.D_E_L_E_T_) IS NULL THEN 0 ELSE 1 END
-
Análise técnica
A trigger de DELETE não cobre esse cenário, pois ela dispara apenas para DELETE físico no banco. No Protheus, o delete comum é lógico, via UPDATE em D_E_L_E_T_. Portanto, a correção deve considerar a trigger de UPDATE Oracle/Protheus.
Sugestão de investigação
Avaliar ajuste na geração da condição da trigger de UPDATE Oracle/Protheus para permitir a transição de registro ativo para deletado lógico, por exemplo considerando o estado anterior e novo de D_E_L_E_T_:
-
registro novo ainda ativo: manter comportamento de update normal;
-
D_E_L_E_T_ mudou de vazio/nulo para preenchido: permitir execução e gravar op_type = 1;
-
preservar o filtro condicional da entidade para registros dentro do escopo.
Resultado esperado
Quando um registro Protheus em Oracle for marcado com D_E_L_E_T_ = '*', a trigger de UPDATE deve inserir entrada na CAROL_3C_QUEUE com op_type = 1, permitindo que a exclusão lógica seja enviada à Carol.