{"id":2265,"date":"2026-08-15T18:18:43","date_gmt":"2026-08-15T21:18:43","guid":{"rendered":"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/"},"modified":"2026-08-15T18:18:43","modified_gmt":"2026-08-15T21:18:43","slug":"aula-20-triggers-plsql-automacao-de-regras-de-negocio","status":"publish","type":"post","link":"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/","title":{"rendered":"Aula 20: Triggers PL\/SQL \u2014 automa\u00e7\u00e3o de regras de neg\u00f3cio"},"content":{"rendered":"<p>As <strong>Triggers PL\/SQL<\/strong> s\u00e3o um dos recursos mais poderosos do Oracle Database para garantir que regras de neg\u00f3cio sejam aplicadas de forma autom\u00e1tica, consistente e independente da aplica\u00e7\u00e3o que acessa os dados. Nesta aula voc\u00ea vai dominar a cria\u00e7\u00e3o, teste e manuten\u00e7\u00e3o dessas estruturas, entendendo exatamente quando e como o banco de dados executa cada bloco de c\u00f3digo vinculado a eventos de <strong>INSERT<\/strong>, <strong>UPDATE<\/strong>, <strong>DELETE<\/strong> e at\u00e9 mesmo a comandos <strong>DDL<\/strong>. Em nossos projetos na JRT Technology Solutions, nossos especialistas utilizam diariamente <strong>Triggers PL\/SQL<\/strong> para implementar trilhas de auditoria, valida\u00e7\u00f5es complexas e integra\u00e7\u00f5es entre tabelas, reduzindo drasticamente a depend\u00eancia de c\u00f3digo duplicado em m\u00faltiplas aplica\u00e7\u00f5es.<\/p>\n<p>Ao final desta aula, voc\u00ea ser\u00e1 capaz de projetar, codificar e validar <strong>Triggers PL\/SQL<\/strong> robustas, entender as diferen\u00e7as entre os tipos dispon\u00edveis, manipular os pseudoregistros <strong>:NEW<\/strong> e <strong>:OLD<\/strong>, evitar os erros cl\u00e1ssicos de <em>mutating table<\/em> e construir uma camada de auditoria real para qualquer tabela do seu banco. Todo o passo a passo foi testado em um ambiente Oracle Database 19c Express Edition rodando em Oracle Linux 8, mas os comandos funcionam perfeitamente nas vers\u00f5es 12c, 18c, 21c e 23ai, tanto em Linux quanto em Windows.<\/p>\n<p>O conte\u00fado desta aula assume que voc\u00ea j\u00e1 concluiu as Aulas 1 a 19 do curso &#8220;Oracle SQL \u2014 Do Zero ao Avan\u00e7ado&#8221;, especialmente os m\u00f3dulos sobre <strong>PL\/SQL<\/strong>, <strong>procedures<\/strong>, <strong>fun\u00e7\u00f5es<\/strong> e <strong>packages<\/strong>. Se voc\u00ea n\u00e3o domina blocos an\u00f4nimos e estruturas de controle do PL\/SQL, recomendamos revisar a Aula 18 antes de prosseguir. Tamb\u00e9m \u00e9 essencial ter acesso a um usu\u00e1rio com privil\u00e9gio <strong>CREATE TRIGGER<\/strong>, como o <strong>HR<\/strong> ou <strong>SYSTEM<\/strong>.<\/p>\n<p>Prepare seu ambiente, abra o <strong>SQL*Plus<\/strong> ou o <strong>Oracle SQL Developer<\/strong> e acompanhe cada comando. Esta \u00e9 uma aula pr\u00e1tica, e a execu\u00e7\u00e3o de cada bloco \u00e9 fundamental para solidificar o aprendizado. Vamos come\u00e7ar entendendo os conceitos que sustentam as <strong>Triggers PL\/SQL<\/strong> e, em seguida, partiremos para a cria\u00e7\u00e3o de exemplos reais que voc\u00ea poder\u00e1 adaptar ao seu ambiente corporativo.<\/p>\n<h3>O que voc\u00ea vai aprender nesta aula<\/h3>\n<ul>\n<li>Compreender o conceito, a finalidade e os componentes principais das <strong>Triggers PL\/SQL<\/strong> no Oracle;<\/li>\n<li>Identificar os eventos de disparo (<strong>INSERT<\/strong>, <strong>UPDATE<\/strong>, <strong>DELETE<\/strong>, <strong>DDL<\/strong>, <strong>logon<\/strong>) e os momentos de execu\u00e7\u00e3o (<strong>BEFORE<\/strong> e <strong>AFTER<\/strong>);<\/li>\n<li>Diferenciar <strong>triggers de linha<\/strong> (<em>row-level<\/em>) de <strong>triggers de instru\u00e7\u00e3o<\/strong> (<em>statement-level<\/em>);<\/li>\n<li>Utilizar os pseudoregistros <strong>:NEW<\/strong> e <strong>:OLD<\/strong> para acessar valores antes e depois das modifica\u00e7\u00f5es;<\/li>\n<li>Criar uma trigger de auditoria completa, gravando automaticamente cada altera\u00e7\u00e3o em uma tabela de log;<\/li>\n<li>Evitar o erro <strong>ORA-04091<\/strong> de <em>mutating table<\/em> e outros problemas comuns;<\/li>\n<li>Consultar dicion\u00e1rios de dados como <strong>USER_TRIGGERS<\/strong> e <strong>USER_SOURCE<\/strong> para gerenciar triggers;<\/li>\n<li>Aplicar boas pr\u00e1ticas de performance e manuten\u00e7\u00e3o em ambientes Oracle de produ\u00e7\u00e3o.<\/li>\n<\/ul>\n<h3>Pr\u00e9-requisitos e Ambiente<\/h3>\n<p>Antes de iniciar esta aula, verifique se o seu ambiente atende aos seguintes requisitos. Voc\u00ea precisar\u00e1 de uma inst\u00e2ncia Oracle Database ativa \u2014 utilizamos o <strong>Oracle Database 19c Express Edition<\/strong> em um servidor Oracle Linux 8, mas qualquer edi\u00e7\u00e3o a partir da 12c serve. O acesso pode ser via <strong>SQL*Plus<\/strong>, <strong>SQLcl<\/strong> ou <strong>Oracle SQL Developer<\/strong>. No nosso laborat\u00f3rio, o usu\u00e1rio de trabalho \u00e9 o <strong>HR<\/strong>, que j\u00e1 possui as tabelas de exemplo <strong>EMPLOYEES<\/strong>, <strong>DEPARTMENTS<\/strong> e <strong>JOBS<\/strong>.<\/p>\n<p>Para verificar se voc\u00ea tem o privil\u00e9gio necess\u00e1rio para criar <strong>Triggers PL\/SQL<\/strong>, conecte-se com o usu\u00e1rio desejado e execute o comando abaixo. A sa\u00edda esperada confirma que o privil\u00e9gio <strong>CREATE TRIGGER<\/strong> est\u00e1 concedido diretamente ou por role ativa.<\/p>\n<pre><code>-- Conectar como HR (ou outro usu\u00e1rio de aplica\u00e7\u00e3o)\n-- No SQL*Plus, use: sqlplus hr\/your_password@localhost:1521\/XEPDB1\n\nSELECT privilege\nFROM   user_sys_privs\nWHERE  privilege = 'CREATE TRIGGER';\n\nSELECT role\nFROM   session_roles\nWHERE  role = 'RESOURCE';<\/code><\/pre>\n<p>Se a primeira consulta n\u00e3o retornar a linha com <strong>CREATE TRIGGER<\/strong>, voc\u00ea pode solicitar ao DBA a concess\u00e3o, ou executar com um usu\u00e1rio administrativo, como <strong>SYSTEM<\/strong>, o seguinte comando de concess\u00e3o:<\/p>\n<pre><code>-- Conceder o privil\u00e9gio de cria\u00e7\u00e3o de triggers ao usu\u00e1rio HR\nGRANT CREATE TRIGGER TO hr;\n\n-- Garantir privil\u00e9gios nas tabelas de exemplo (se necess\u00e1rio)\nGRANT SELECT, INSERT, UPDATE, DELETE ON hr.employees TO hr;<\/code><\/pre>\n<p>Criaremos tamb\u00e9m uma tabela de auditoria chamada <strong>AUDIT_EMPLOYEES<\/strong> para registrar todas as opera\u00e7\u00f5es de <strong>DML<\/strong> sobre a tabela <strong>EMPLOYEES<\/strong>. Todas as tabelas, sequ\u00eancias e triggers criadas nesta aula ficar\u00e3o no schema <strong>HR<\/strong>. Se voc\u00ea estiver usando outro schema, basta adaptar os nomes nos exemplos. Recomendamos fortemente seguir o passo a passo na ordem apresentada para evitar gaps de configura\u00e7\u00e3o.<\/p>\n<p>Durante a aula, utilizaremos o <strong>SQL*Plus<\/strong> com formata\u00e7\u00e3o de sa\u00edda ajustada para facilitar a leitura. Os comandos <strong>SET LINESIZE<\/strong>, <strong>SET PAGESIZE<\/strong> e <strong>COLUMN<\/strong> ser\u00e3o exibidos antes de cada consulta relevante. Caso prefira o <strong>Oracle SQL Developer<\/strong>, os mesmos comandos SQL e PL\/SQL funcionam sem modifica\u00e7\u00f5es.<\/p>\n<h3>Conceitos Fundamentais de Triggers PL\/SQL<\/h3>\n<p>Uma <strong>trigger PL\/SQL<\/strong> \u00e9 um bloco de c\u00f3digo armazenado no banco de dados que o Oracle executa automaticamente quando um evento especificado ocorre em uma tabela, view, schema ou banco de dados. Diferente de uma <strong>procedure<\/strong> ou <strong>function<\/strong>, que precisam ser chamadas explicitamente por um usu\u00e1rio ou aplica\u00e7\u00e3o, a trigger \u00e9 disparada de forma impl\u00edcita pelo pr\u00f3prio motor do Oracle. Isso garante que a l\u00f3gica nela contida seja aplicada sempre, independentemente da origem da opera\u00e7\u00e3o \u2014 seja via <strong>SQL*Plus<\/strong>, aplica\u00e7\u00e3o Java, .NET, Python ou qualquer outra ferramenta que se conecte ao banco.<\/p>\n<p>Os componentes essenciais de uma trigger s\u00e3o: o <strong>evento<\/strong> que dispara a execu\u00e7\u00e3o (como <strong>BEFORE INSERT ON employees<\/strong>), o <strong>timing<\/strong> (<strong>BEFORE<\/strong> ou <strong>AFTER<\/strong>), o <strong>n\u00edvel<\/strong> (<strong>ROW<\/strong> ou <strong>STATEMENT<\/strong>), a <strong>condi\u00e7\u00e3o opcional<\/strong> (<strong>WHEN<\/strong>) e o <strong>corpo PL\/SQL<\/strong> com a l\u00f3gica a executar. A sintaxe completa pode ser expressa da seguinte forma resumida:<\/p>\n<pre><code>CREATE [OR REPLACE] TRIGGER nome_trigger\n    BEFORE | AFTER | INSTEAD OF evento ON tabela_ou_view\n    [FOR EACH ROW]\n    [WHEN (condicao)]\n    [DECLARE ...]\n    BEGIN\n        -- comandos PL\/SQL\n    END;\n\/<\/code><\/pre>\n<p>Quando usamos <strong>FOR EACH ROW<\/strong>, a trigger \u00e9 classificada como <em>row-level<\/em> e executa uma vez para cada linha afetada pela instru\u00e7\u00e3o <strong>DML<\/strong>. Sem essa cl\u00e1usula, ela \u00e9 <em>statement-level<\/em> e executa apenas uma vez para a instru\u00e7\u00e3o como um todo. Essa distin\u00e7\u00e3o \u00e9 cr\u00edtica: em uma atualiza\u00e7\u00e3o de 10.000 linhas, uma trigger <strong>FOR EACH ROW<\/strong> executar\u00e1 10.000 vezes, enquanto uma trigger sem <strong>FOR EACH ROW<\/strong> executar\u00e1 apenas uma \u00fanica vez. A escolha errada pode causar graves problemas de performance.<\/p>\n<p>Os pseudoregistros <strong>:NEW<\/strong> e <strong>:OLD<\/strong> s\u00e3o exclusivos de triggers <em>row-level<\/em> e representam, respectivamente, os valores novos e antigos de cada coluna da linha sendo processada. Em um <strong>INSERT<\/strong>, apenas <strong>:NEW<\/strong> est\u00e1 dispon\u00edvel; em um <strong>DELETE<\/strong>, apenas <strong>:OLD<\/strong>; em um <strong>UPDATE<\/strong>, ambos est\u00e3o dispon\u00edveis. Essa capacidade de acessar e alterar valores antes da grava\u00e7\u00e3o f\u00edsica \u00e9 o que torna as <strong>Triggers PL\/SQL<\/strong> ideais para valida\u00e7\u00f5es, padroniza\u00e7\u00e3o de dados e auditoria.<\/p>\n<p>\u00c9 importante entender tamb\u00e9m o conceito de <strong>timing<\/strong>. Uma trigger <strong>BEFORE<\/strong> executa antes da a\u00e7\u00e3o <strong>DML<\/strong> ser efetivada na tabela, permitindo alterar valores em <strong>:NEW<\/strong> ou abortar a opera\u00e7\u00e3o com <strong>RAISE_APPLICATION_ERROR<\/strong>. Uma trigger <strong>AFTER<\/strong> executa ap\u00f3s a grava\u00e7\u00e3o, sendo ideal para registrar logs, atualizar tabelas de resumo ou invocar outros processos. J\u00e1 as triggers <strong>INSTEAD OF<\/strong> s\u00e3o usadas principalmente em <strong>views<\/strong> n\u00e3o atualiz\u00e1veis diretamente, interceptando o comando <strong>DML<\/strong> e definindo manualmente o que deve ser feito nas tabelas base.<\/p>\n<h3>Criando a Primeira Trigger PL\/SQL Passo a Passo<\/h3>\n<p>Vamos partir para a pr\u00e1tica. Nosso primeiro objetivo \u00e9 criar uma trigger de auditoria que registre automaticamente cada inser\u00e7\u00e3o de funcion\u00e1rio na tabela <strong>EMPLOYEES<\/strong>. Antes da trigger, precisamos de uma estrutura de destino para os registros de auditoria. Criaremos a tabela <strong>AUDIT_EMPLOYEES<\/strong> com os campos essenciais: identificador sequencial, opera\u00e7\u00e3o realizada, usu\u00e1rio que executou, data\/hora, e os valores relevantes do funcion\u00e1rio. Tamb\u00e9m criaremos uma <strong>sequence<\/strong> para gerar o identificador \u00fanico.<\/p>\n<p>Neste exemplo, o contexto \u00e9 o de uma empresa que precisa manter trilha de auditoria de todas as inclus\u00f5es de funcion\u00e1rios, atendendo requisitos de conformidade e seguran\u00e7a da informa\u00e7\u00e3o. Em projetos na JRT Technology Solutions, nossos especialistas frequentemente modelam tabelas de auditoria com colunas de metadados como <strong>USERNAME<\/strong>, <strong>SYSDATE<\/strong> e <strong>OPERATION_TYPE<\/strong>, exatamente como faremos aqui. Siga os comandos abaixo na ordem exata.<\/p>\n<ol>\n<li><strong>Crie a tabela de auditoria:<\/strong> ela armazenar\u00e1 os registros gerados pela trigger. As colunas <strong>OLD_VALUE<\/strong> e <strong>NEW_VALUE<\/strong> podem ser usadas para armazenar valores antigos e novos conforme a opera\u00e7\u00e3o.<\/li>\n<li><strong>Crie a sequence:<\/strong> a sequence <strong>SEQ_AUDIT_EMP<\/strong> fornecer\u00e1 o pr\u00f3ximo valor para a chave prim\u00e1ria <strong>AUDIT_ID<\/strong>.<\/li>\n<li><strong>Crie a trigger <strong>BEFORE INSERT<\/strong>:<\/strong> ela ser\u00e1 executada antes de cada <strong>INSERT<\/strong> na tabela <strong>EMPLOYEES<\/strong>, gravando o registro de auditoria.<\/li>\n<li><strong>Teste a trigger:<\/strong> execute um <strong>INSERT<\/strong> na tabela <strong>EMPLOYEES<\/strong> e confirme se o registro foi gerado em <strong>AUDIT_EMPLOYEES<\/strong>.<\/li>\n<li><strong>Verifique os dados:<\/strong> consulte a tabela de auditoria para validar o funcionamento.<\/li>\n<\/ol>\n<p>Execute o bloco abaixo no <strong>SQL*Plus<\/strong> para criar a tabela de auditoria e a sequence. A sa\u00edda esperada \u00e9 a mensagem <strong>Table created.<\/strong> seguida de <strong>Sequence created.<\/strong><\/p>\n<pre><code>-- =========================================================\n-- Passo 1: Criar a tabela de auditoria de funcionarios\n-- =========================================================\nCREATE TABLE audit_employees (\n    audit_id        NUMBER PRIMARY KEY,\n    operation_type  VARCHAR2(10)  NOT NULL,\n    employee_id     NUMBER,\n    first_name      VARCHAR2(20),\n    last_name       VARCHAR2(25),\n    old_salary      NUMBER(8,2),\n    new_salary      NUMBER(8,2),\n    username        VARCHAR2(30)  NOT NULL,\n    audit_date      DATE          NOT NULL\n);\n\n-- =========================================================\n-- Passo 2: Criar sequence para a chave primaria\n-- =========================================================\nCREATE SEQUENCE seq_audit_emp\n    START WITH 1\n    INCREMENT BY 1\n    NOCACHE\n    NOCYCLE;<\/code><\/pre>\n<pre><code class=\"output\">Table created.\n\nSequence created.<\/code><\/pre>\n<p>A tabela <strong>AUDIT_EMPLOYEES<\/strong> possui uma coluna <strong>AUDIT_ID<\/strong> que ser\u00e1 preenchida com o pr\u00f3ximo valor da sequence <strong>SEQ_AUDIT_EMP<\/strong> via <strong>NEXTVAL<\/strong>. As colunas <strong>OLD_SALARY<\/strong> e <strong>NEW_SALARY<\/strong> permitir\u00e3o rastrear altera\u00e7\u00f5es salariais em auditorias de <strong>UPDATE<\/strong> futuras. Agora, vamos criar a trigger propriamente dita. Note a cl\u00e1usula <strong>CREATE OR REPLACE TRIGGER<\/strong>, que permite recriar a trigger sem precisar descart\u00e1-la primeiro.<\/p>\n<pre><code>-- =========================================================\n-- Passo 3: Criar trigger de auditoria para INSERT em EMPLOYEES\n-- =========================================================\nCREATE OR REPLACE TRIGGER trg_audit_emp_insert\n    BEFORE INSERT ON employees\n    FOR EACH ROW\nDECLARE\n    v_operation VARCHAR2(10) := 'INSERT';\nBEGIN\n    INSERT INTO audit_employees (\n        audit_id,\n        operation_type,\n        employee_id,\n        first_name,\n        last_name,\n        old_salary,\n        new_salary,\n        username,\n        audit_date\n    ) VALUES (\n        seq_audit_emp.NEXTVAL,\n        v_operation,\n        :NEW.employee_id,\n        :NEW.first_name,\n        :NEW.last_name,\n        NULL,               -- old_salary: nao existe em INSERT\n        :NEW.salary,        -- new_salary: valor novo do salario\n        USER,               -- usuario Oracle que executou o INSERT\n        SYSDATE             -- data\/hora exata da operacao\n    );\nEND;\n\/<\/code><\/pre>\n<pre><code class=\"output\">Trigger created.<\/code><\/pre>\n<p>Na trigger <strong>TRG_AUDIT_EMP_INSERT<\/strong>, usamos <strong>BEFORE INSERT ON employees<\/strong> para garantir que a grava\u00e7\u00e3o na tabela de auditoria ocorra antes da inser\u00e7\u00e3o do funcion\u00e1rio. A cl\u00e1usula <strong>FOR EACH ROW<\/strong> indica que o c\u00f3digo executar\u00e1 uma vez para cada linha inserida. Dentro do bloco, declaramos uma vari\u00e1vel local <strong>v_operation<\/strong> com valor fixo <strong>&#8216;INSERT&#8217;<\/strong> e realizamos o <strong>INSERT<\/strong> em <strong>AUDIT_EMPLOYEES<\/strong> utilizando <strong>seq_audit_emp.NEXTVAL<\/strong> para gerar o <strong>AUDIT_ID<\/strong>. Os valores <strong>:NEW.employee_id<\/strong>, <strong>:NEW.first_name<\/strong>, <strong>:NEW.last_name<\/strong> e <strong>:NEW.salary<\/strong> acessam os dados que est\u00e3o sendo inseridos na tabela <strong>EMPLOYEES<\/strong>.<\/p>\n<p>Agora vamos testar a trigger executando uma inser\u00e7\u00e3o real na tabela <strong>EMPLOYEES<\/strong>. Antes, consultamos o \u00faltimo <strong>EMPLOYEE_ID<\/strong> para n\u00e3o violar a restri\u00e7\u00e3o de chave prim\u00e1ria. Em seguida, inserimos um novo funcion\u00e1rio e verificamos se o registro de auditoria foi criado automaticamente.<\/p>\n<pre><code>-- =========================================================\n-- Passo 4: Testar a trigger com um INSERT real\n-- =========================================================\n-- Consultar o maior EMPLOYEE_ID existente\nSELECT MAX(employee_id) AS max_id FROM employees;\n\n-- Inserir um novo funcionario (ajuste o ID conforme necessario)\nINSERT INTO employees (\n    employee_id,\n    first_name,\n    last_name,\n    email,\n    phone_number,\n    hire_date,\n    job_id,\n    salary,\n    commission_pct,\n    manager_id,\n    department_id\n) VALUES (\n    207,\n    'Maria',\n    'Silva',\n    'MSILVA',\n    '515.123.9999',\n    TO_DATE('2026-08-15', 'YYYY-MM-DD'),\n    'IT_PROG',\n    7500,\n    NULL,\n    103,\n    60\n);\n\n-- Confirmar a transacao\nCOMMIT;<\/code><\/pre>\n<pre><code class=\"output\">  MAX_ID\n----------\n      206\n\n1 row created.\n\nCommit complete.<\/code><\/pre>\n<p>Ap\u00f3s o <strong>COMMIT<\/strong>, a transa\u00e7\u00e3o foi efetivada e a trigger foi executada automaticamente. Para confirmar, vamos consultar a tabela <strong>AUDIT_EMPLOYEES<\/strong> e verificar se o registro de auditoria foi gravado corretamente, com o nome da funcion\u00e1ria, o sal\u00e1rio novo e o usu\u00e1rio que executou a opera\u00e7\u00e3o.<\/p>\n<pre><code>-- =========================================================\n-- Passo 5: Verificar a tabela de auditoria\n-- =========================================================\nSET LINESIZE 200\nSET PAGESIZE 100\nCOLUMN operation_type FORMAT A15\nCOLUMN first_name     FORMAT A15\nCOLUMN last_name      FORMAT A15\nCOLUMN username       FORMAT A15\nCOLUMN old_salary     FORMAT 999999.99\nCOLUMN new_salary     FORMAT 999999.99\n\nSELECT audit_id,\n       operation_type,\n       employee_id,\n       first_name,\n       last_name,\n       old_salary,\n       new_salary,\n       username,\n       TO_CHAR(audit_date, 'YYYY-MM-DD HH24:MI:SS') AS audit_date\nFROM   audit_employees\nORDER  BY audit_id;<\/code><\/pre>\n<pre><code class=\"output\">  AUDIT_ID OPERATION_TYPE EMPLOYEE_ID FIRST_NAME      LAST_NAME       OLD_SALARY NEW_SALARY USERNAME        AUDIT_DATE\n---------- -------------- ----------- --------------- --------------- ---------- ---------- --------------- -------------------\n         1 INSERT                  207 Maria           Silva                    0.00   7500.00 HR              2026-08-15 14:32:18\n\n1 row selected.<\/code><\/pre>\n<p>O resultado confirma que a trigger <strong>TRG_AUDIT_EMP_INSERT<\/strong> funcionou corretamente. A coluna <strong>AUDIT_ID<\/strong> foi preenchida com o valor 1 da sequence, <strong>OPERATION_TYPE<\/strong> indica <strong>INSERT<\/strong>, <strong>EMPLOYEE_ID<\/strong> 207 corresponde ao funcion\u00e1rio inserido, e <strong>AUDIT_DATE<\/strong> registra o exato momento da opera\u00e7\u00e3o. Esse padr\u00e3o de auditoria \u00e9 extremamente valioso para trilhas de conformidade e investiga\u00e7\u00f5es de seguran\u00e7a, e \u00e9 amplamente utilizado nos projetos de implementa\u00e7\u00e3o da JRT Technology Solutions.<\/p>\n<h3>Tipos de Triggers PL\/SQL \u2014 BEFORE, AFTER, INSTEAD OF e Triggers de Sistema<\/h3>\n<p>O Oracle classifica as <strong>Triggers PL\/SQL<\/strong> em categorias de acordo com o timing, o objeto alvo e o tipo de evento. As triggers de <strong>DML<\/strong> (Data Manipulation Language) s\u00e3o as mais comuns e disparam em opera\u00e7\u00f5es de <strong>INSERT<\/strong>, <strong>UPDATE<\/strong> e <strong>DELETE<\/strong> sobre tabelas ou views. Dentro desse grupo, temos as op\u00e7\u00f5es <strong>BEFORE<\/strong> e <strong>AFTER<\/strong>, cada uma com finalidades espec\u00edficas. As triggers <strong>BEFORE<\/strong> s\u00e3o ideais para valida\u00e7\u00f5es, normaliza\u00e7\u00e3o de dados e verifica\u00e7\u00e3o de regras de neg\u00f3cio, pois podem modificar o valor de <strong>:NEW<\/strong> antes da grava\u00e7\u00e3o.<\/p>\n<p>As triggers <strong>AFTER<\/strong> s\u00e3o recomendadas para auditoria, atualiza\u00e7\u00e3o de tabelas de resumo, manuten\u00e7\u00e3o de cache e integra\u00e7\u00e3o com processos ass\u00edncronos. Ao contr\u00e1rio das <strong>BEFORE<\/strong>, elas n\u00e3o podem alterar os valores de <strong>:NEW<\/strong>, pois a linha j\u00e1 foi gravada. No entanto, s\u00e3o perfeitas para registrar logs de opera\u00e7\u00f5es, como fizemos na trigger <strong>TRG_AUDIT_EMP_INSERT<\/strong> \u2014 na verdade, utilizamos <strong>BEFORE<\/strong> para garantir que, se houvesse falha no <strong>INSERT<\/strong> em <strong>EMPLOYEES<\/strong>, a auditoria tamb\u00e9m fosse revertida automaticamente pela atomicidade da transa\u00e7\u00e3o.<\/p>\n<p>As triggers <strong>INSTEAD OF<\/strong> s\u00e3o um caso especial: elas s\u00e3o criadas sobre <strong>views<\/strong> e \u201csubstituem\u201d a opera\u00e7\u00e3o <strong>DML<\/strong> original. Em vez de tentar inserir, atualizar ou excluir diretamente na view \u2014 o que muitas vezes \u00e9 imposs\u00edvel em views complexas com joins ou fun\u00e7\u00f5es de agrega\u00e7\u00e3o \u2014 a trigger executa comandos <strong>DML<\/strong> nas tabelas base para simular a opera\u00e7\u00e3o. Essa t\u00e9cnica \u00e9 comum em projetos de integra\u00e7\u00e3o onde uma view apresenta dados de m\u00faltiplas tabelas e a aplica\u00e7\u00e3o precisa de uma interface de escrita \u00fanica.<\/p>\n<p>Al\u00e9m das triggers de <strong>DML<\/strong>, existem as <strong>triggers de sistema<\/strong>, tamb\u00e9m chamadas de <strong>DDL<\/strong> ou <strong>database triggers<\/strong>. Elas disparam em eventos como <strong>CREATE<\/strong>, <strong>ALTER<\/strong>, <strong>DROP<\/strong>, <strong>LOGON<\/strong>, <strong>LOGOFF<\/strong>, <strong>STARTUP<\/strong> e <strong>SHUTDOWN<\/strong>. Essas triggers s\u00e3o criadas com a sintaxe <strong>ON DATABASE<\/strong> ou <strong>ON SCHEMA<\/strong> e exigem privil\u00e9gios administrativos como <strong>ADMINISTER DATABASE TRIGGER<\/strong>. S\u00e3o usadas para monitorar altera\u00e7\u00f5es estruturais, definir pol\u00edticas de seguran\u00e7a e restringir comandos perigosos em produ\u00e7\u00e3o.<\/p>\n<p>A tabela a seguir resume os principais tipos de <strong>Triggers PL\/SQL<\/strong>, seus eventos de disparo e aplica\u00e7\u00f5es t\u00edpicas:<\/p>\n<table border=\"1\" cellpadding=\"8\" cellspacing=\"0\">\n<thead>\n<tr>\n<th>Tipo de Trigger<\/th>\n<th>Evento Disparador<\/th>\n<th>N\u00edvel<\/th>\n<th>Uso Comum<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>BEFORE INSERT<\/strong><\/td>\n<td>Inser\u00e7\u00e3o em tabela<\/td>\n<td>Row ou Statement<\/td>\n<td>Valida\u00e7\u00e3o, normaliza\u00e7\u00e3o, preenchimento de colunas<\/td>\n<\/tr>\n<tr>\n<td><strong>AFTER INSERT<\/strong><\/td>\n<td>Inser\u00e7\u00e3o em tabela<\/td>\n<td>Row ou Statement<\/td>\n<td>Auditoria, atualiza\u00e7\u00e3o de resumos<\/td>\n<\/tr>\n<tr>\n<td><strong>BEFORE UPDATE<\/strong><\/td>\n<td>Atualiza\u00e7\u00e3o em tabela<\/td>\n<td>Row ou Statement<\/td>\n<td>Verificar mudan\u00e7a de sal\u00e1rio, impedir updates indevidos<\/td>\n<\/tr>\n<tr>\n<td><strong>AFTER UPDATE<\/strong><\/td>\n<td>Atualiza\u00e7\u00e3o em tabela<\/td>\n<td>Row ou Statement<\/td>\n<td>Registrar hist\u00f3rico de mudan\u00e7as<\/td>\n<\/tr>\n<tr>\n<td><strong>BEFORE DELETE<\/strong><\/td>\n<td>Exclus\u00e3o em tabela<\/td>\n<td>Row ou Statement<\/td>\n<td>Impedir exclus\u00e3o de registros protegidos<\/td>\n<\/tr>\n<tr>\n<td><strong>AFTER DELETE<\/strong><\/td>\n<td>Exclus\u00e3o em tabela<\/td>\n<td>Row ou Statement<\/td>\n<td>Auditoria, propaga\u00e7\u00e3o de exclus\u00e3o<\/td>\n<\/tr>\n<tr>\n<td><strong>INSTEAD OF<\/strong><\/td>\n<td>DML em view<\/td>\n<td>Row<\/td>\n<td>Permitir escrita em views complexas<\/td>\n<\/tr>\n<tr>\n<td><strong>DDL \/ DATABASE<\/strong><\/td>\n<td>CREATE, ALTER, DROP, GRANT, LOGON, etc.<\/td>\n<td>Schema ou Database<\/td>\n<td>Seguran\u00e7a, monitoramento de estrutura<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>A escolha correta entre <strong>BEFORE<\/strong>, <strong>AFTER<\/strong> e <strong>INSTEAD OF<\/strong> exige an\u00e1lise cuidadosa da regra de neg\u00f3cio e do impacto na transa\u00e7\u00e3o. Por exemplo, se a inten\u00e7\u00e3o \u00e9 impedir que um usu\u00e1rio modifique determinada coluna, a melhor op\u00e7\u00e3o \u00e9 uma trigger <strong>BEFORE UPDATE<\/strong> que compare <strong>:OLD.coluna<\/strong> com <strong>:NEW.coluna<\/strong> e levante uma exce\u00e7\u00e3o. Se a inten\u00e7\u00e3o \u00e9 gravar um log ap\u00f3s a altera\u00e7\u00e3o, use <strong>AFTER UPDATE<\/strong>. Em cen\u00e1rios de views, o <strong>INSTEAD OF<\/strong> \u00e9 indispens\u00e1vel.<\/p>\n<h3>Triggers PL\/SQL de Linha vs Instru\u00e7\u00e3o \u2014 Quando Usar Cada Uma<\/h3>\n<p>A cl\u00e1usula <strong>FOR EACH ROW<\/strong> define se a trigger ser\u00e1 executada uma vez para cada linha afetada (<em>row-level<\/em>) ou uma \u00fanica vez para a instru\u00e7\u00e3o <strong>SQL<\/strong> inteira (<em>statement-level<\/em>). A diferen\u00e7a pr\u00e1tica \u00e9 gigantesca em termos de performance e sem\u00e2ntica. Em uma trigger <em>row-level<\/em>, voc\u00ea tem acesso aos pseudoregistros <strong>:NEW<\/strong> e <strong>:OLD<\/strong>, podendo analisar e modificar valores individualmente. Em uma trigger <em>statement-level<\/em>, esses pseudoregistros n\u00e3o existem, pois a l\u00f3gica opera no conjunto de linhas como um todo.<\/p>\n<p>Considere uma tabela com 50.000 funcion\u00e1rios e uma opera\u00e7\u00e3o de <strong>UPDATE<\/strong> que atualiza o sal\u00e1rio de todos. Se criarmos uma trigger <strong>AFTER UPDATE ON employees FOR EACH ROW<\/strong>, ela executar\u00e1 50.000 vezes \u2014 uma para cada linha alterada. Se a mesma trigger for criada sem <strong>FOR EACH ROW<\/strong>, executar\u00e1 apenas uma vez. Em termos de overhead, a primeira pode ser proibitiva em ambientes de alta concorr\u00eancia. Por outro lado, se a regra exige verificar o valor de uma coluna em cada linha, como impedir sal\u00e1rio acima de um teto, a trigger <em>row-level<\/em> \u00e9 obrigat\u00f3ria.<\/p>\n<p>Vamos demonstrar a diferen\u00e7a com um exemplo pr\u00e1tico. Criaremos uma tabela de log gen\u00e9rica para registrar opera\u00e7\u00f5es em lote e uma trigger <em>statement-level<\/em> que conta quantas linhas foram afetadas por um <strong>DELETE<\/strong>. Para isso, usaremos a fun\u00e7\u00e3o <strong>SQL%ROWCOUNT<\/strong>, que retorna o n\u00famero de linhas processadas pela instru\u00e7\u00e3o. A trigger registrar\u00e1 essa contagem em uma tabela de log.<\/p>\n<pre><code>-- =========================================================\n-- Criar tabela de log para instrucoes DML em lote\n-- =========================================================\nCREATE TABLE dml_log (\n    log_id      NUMBER PRIMARY KEY,\n    operation   VARCHAR2(20),\n    row_count   NUMBER,\n    username    VARCHAR2(30),\n    log_date    DATE\n);\n\n-- Sequence para DML_LOG\nCREATE SEQUENCE seq_dml_log\n    START WITH 1\n    INCREMENT BY 1\n    NOCACHE;\n\n-- =========================================================\n-- Trigger statement-level para registrar contagem de DELETE\n-- =========================================================\nCREATE OR REPLACE TRIGGER trg_log_delete_emp\n    BEFORE DELETE ON employees\n    -- Sem FOR EACH ROW: executa uma unica vez por instrucao\nDECLARE\n    v_count NUMBER;\nBEGIN\n    -- SQL%ROWCOUNT aqui e 0, pois ainda nao processou linhas\n    -- Mas podemos usar uma variavel para capturar depois\n    NULL;\nEND;\n\/<\/code><\/pre>\n<p>O exemplo acima, por\u00e9m, n\u00e3o \u00e9 eficiente para capturar a contagem em <strong>BEFORE<\/strong>, pois <strong>SQL%ROWCOUNT<\/strong> ainda \u00e9 zero. Para registrar corretamente o n\u00famero de linhas afetadas, o ideal \u00e9 usar uma trigger <strong>AFTER DELETE<\/strong> sem <strong>FOR EACH ROW<\/strong>, onde <strong>SQL%ROWCOUNT<\/strong> reflete o total de linhas exclu\u00eddas. Vamos corrigir o exemplo:<\/p>\n<pre><code>-- =========================================================\n-- Trigger statement-level AFTER DELETE para contagem real\n-- =========================================================\nCREATE OR REPLACE TRIGGER trg_log_delete_emp_after\n    AFTER DELETE ON employees\n    -- Sem FOR EACH ROW: executa uma unica vez por instrucao\nBEGIN\n    INSERT INTO dml_log (\n        log_id,\n        operation,\n        row_count,\n        username,\n        log_date\n    ) VALUES (\n        seq_dml_log.NEXTVAL,\n        'DELETE',\n        SQL%ROWCOUNT,          -- Retorna o total de linhas afetadas\n        USER,\n        SYSDATE\n    );\nEND;\n\/<\/code><\/pre>\n<pre><code class=\"output\">Trigger created.<\/code><\/pre>\n<p>A trigger <strong>TRG_LOG_DELETE_EMP_AFTER<\/strong> registra, ap\u00f3s cada <strong>DELETE<\/strong> na tabela <strong>EMPLOYEES<\/strong>, o n\u00famero total de linhas exclu\u00eddas pela instru\u00e7\u00e3o. Se um <strong>DELETE<\/strong> remover 200 funcion\u00e1rios de uma vez, a trigger executar\u00e1 apenas uma vez e gravar\u00e1 <strong>row_count = 200<\/strong>. Se a trigger tivesse <strong>FOR EACH ROW<\/strong>, executaria 200 vezes e, para cada execu\u00e7\u00e3o, <strong>SQL%ROWCOUNT<\/strong> retornaria 1, tornando a l\u00f3gica inadequada. Esse exemplo evidencia a import\u00e2ncia de escolher corretamente o n\u00edvel da trigger.<\/p>\n<p>Outra vantagem das triggers <em>statement-level<\/em> \u00e9 a aus\u00eancia do erro <strong>ORA-04091<\/strong> de <em>mutating table<\/em>, que ocorre apenas em triggers <em>row-level<\/em> ao tentar consultar ou modificar a pr\u00f3pria tabela que disparou o evento. Se voc\u00ea precisa executar uma l\u00f3gica que l\u00ea a tabela alvo, a trigger <em>statement-level<\/em> pode ser a solu\u00e7\u00e3o, pois o Oracle j\u00e1 concluiu a opera\u00e7\u00e3o <strong>DML<\/strong> quando ela \u00e9 executada (no caso de <strong>AFTER<\/strong>).<\/p>\n<h3>Trabalhando com :NEW e :OLD em Triggers PL\/SQL<\/h3>\n<p>Os pseudoregistros <strong>:NEW<\/strong> e <strong>:OLD<\/strong> s\u00e3o fundamentais para a programa\u00e7\u00e3o de <strong>Triggers PL\/SQL<\/strong> de linha. Eles fornecem uma vis\u00e3o dos valores das colunas antes e depois da opera\u00e7\u00e3o <strong>DML<\/strong>, permitindo compara\u00e7\u00f5es, valida\u00e7\u00f5es e ajustes. Em uma trigger <strong>BEFORE INSERT<\/strong>, apenas <strong>:NEW<\/strong> est\u00e1 dispon\u00edvel; em <strong>BEFORE DELETE<\/strong>, apenas <strong>:OLD<\/strong>; em <strong>BEFORE UPDATE<\/strong>, ambos. Acesso a pseudoregistros em triggers <em>statement-level<\/em> gera erro de compila\u00e7\u00e3o.<\/p>\n<p>Vamos criar uma trigger que impe\u00e7a a redu\u00e7\u00e3o de sal\u00e1rio de um funcion\u00e1rio. A regra de neg\u00f3cio \u00e9 simples: nenhum <strong>UPDATE<\/strong> na tabela <strong>EMPLOYEES<\/strong> pode diminuir o valor da coluna <strong>SALARY<\/strong>. Se a tentativa ocorrer, a trigger deve lan\u00e7ar uma exce\u00e7\u00e3o com <strong>RAISE_APPLICATION_ERROR<\/strong> e abortar a opera\u00e7\u00e3o. Esse tipo de prote\u00e7\u00e3o garante que nem mesmo um DBA descuidado ou uma aplica\u00e7\u00e3o mal configurada consiga violar a pol\u00edtica.<\/p>\n<pre><code>-- =========================================================\n-- Trigger para impedir redu\u00e7\u00e3o de salario\n-- =========================================================\nCREATE OR REPLACE TRIGGER trg_no_salary_decrease\n    BEFORE UPDATE OF salary ON employees\n    FOR EACH ROW\nDECLARE\n    v_old_salary NUMBER;\n    v_new_salary NUMBER;\nBEGIN\n    v_old_salary := :OLD.salary;\n    v_new_salary := :NEW.salary;\n\n    IF v_new_salary < v_old_salary THEN\n        RAISE_APPLICATION_ERROR(\n            -20001,\n            'Reducao de salario nao permitida! ' ||\n            'Salario atual: ' || v_old_salary || ', ' ||\n            'Salario proposto: ' || v_new_salary\n        );\n    END IF;\nEND;\n\/<\/code><\/pre>\n<pre><code class=\"output\">Trigger created.<\/code><\/pre>\n<p>Na trigger <strong>TRG_NO_SALARY_DECREASE<\/strong>, usamos a cl\u00e1usula <strong>BEFORE UPDATE OF salary<\/strong>, que restringe o disparo apenas a atualiza\u00e7\u00f5es na coluna <strong>SALARY<\/strong> \u2014 se outras colunas forem alteradas, a trigger n\u00e3o executa. Os valores s\u00e3o capturados com <strong>:OLD.salary<\/strong> e <strong>:NEW.salary<\/strong> e comparados em uma estrutura <strong>IF<\/strong>. Se o novo sal\u00e1rio for menor que o antigo, a exce\u00e7\u00e3o <strong>ORA-20001<\/strong> \u00e9 lan\u00e7ada, interrompendo a transa\u00e7\u00e3o.<\/p>\n<p>Para testar, vamos tentar reduzir o sal\u00e1rio do funcion\u00e1rio 207 de 7500 para 6000. A trigger deve bloquear a opera\u00e7\u00e3o e exibir a mensagem de erro personalizada. Em seguida, faremos uma atualiza\u00e7\u00e3o v\u00e1lida aumentando o sal\u00e1rio, que deve ser aceita normalmente.<\/p>\n<pre><code>-- =========================================================\n-- Testar bloqueio de redu\u00e7\u00e3o de salario\n-- =========================================================\nSET SERVEROUTPUT ON\n\n-- Tentativa invalida: reduzir salario de 7500 para 6000\nUPDATE employees\nSET    salary = 6000\nWHERE  employee_id = 207;<\/code><\/pre>\n<pre><code class=\"output\">UPDATE employees\n       *\nERROR at line 1:\nORA-20001: Reducao de salario nao permitida! Salario atual: 7500, Salario proposto: 6000\nORA-06512: at \"HR.TRG_NO_SALARY_DECREASE\", line 9\nORA-04088: error during execution of trigger 'HR.TRG_NO_SALARY_DECREASE'<\/code><\/pre>\n<p>O erro <strong>ORA-20001<\/strong> comprova que a trigger bloqueou a opera\u00e7\u00e3o. A stack trace mostra o caminho da exce\u00e7\u00e3o: primeiro a mensagem personalizada, depois a linha 9 da trigger e, por fim, o erro <strong>ORA-04088<\/strong> indicando falha na execu\u00e7\u00e3o da trigger. Em um ambiente real, esse tipo de bloqueio pode ser registrado em logs de auditoria do banco e monitorado por ferramentas de SIEM, alinhado \u00e0s pr\u00e1ticas de seguran\u00e7a da JRT Technology Solutions.<\/p>\n<p>Agora vamos executar uma atualiza\u00e7\u00e3o v\u00e1lida, aumentando o sal\u00e1rio para 8000. A trigger n\u00e3o deve levantar erro, e a transa\u00e7\u00e3o deve ser confirmada com sucesso. Depois consultamos a tabela <strong>EMPLOYEES<\/strong> para verificar o valor atualizado.<\/p>\n<pre><code>-- =========================================================\n-- Atualizacao valida: aumentar salario de 7500 para 8000\n-- =========================================================\nUPDATE employees\nSET    salary = 8000\nWHERE  employee_id = 207;\n\nCOMMIT;<\/code><\/pre>\n<pre><code class=\"output\">1 row updated.\n\nCommit complete.<\/code><\/pre>\n<p>O uso de <strong>:NEW<\/strong> e <strong>:OLD<\/strong> tamb\u00e9m \u00e9 comum para preencher automaticamente colunas de auditoria, como <strong>CREATED_BY<\/strong>, <strong>CREATED_DATE<\/strong>, <strong>UPDATED_BY<\/strong> e <strong>UPDATED_DATE<\/strong>. Por exemplo, uma trigger <strong>BEFORE INSERT<\/strong> pode definir <strong>:NEW.created_by := USER<\/strong> e <strong>:NEW.created_date := SYSDATE<\/strong>, enquanto uma <strong>BEFORE UPDATE<\/strong> atualiza as colunas de modifica\u00e7\u00e3o. Isso retira a responsabilidade da aplica\u00e7\u00e3o e garante a integridade dos metadados de auditoria.<\/p>\n<h3>Triggers DDL e de Banco de Dados para Auditoria Avan\u00e7ada<\/h3>\n<p>As <strong>Triggers PL\/SQL<\/strong> de <strong>DDL<\/strong> s\u00e3o uma categoria especial que dispara em eventos estruturais, como cria\u00e7\u00e3o, altera\u00e7\u00e3o ou exclus\u00e3o de objetos, concess\u00e3o de privil\u00e9gios e at\u00e9 mesmo conex\u00e3o de usu\u00e1rios. Elas s\u00e3o criadas com a cl\u00e1usula <strong>ON DATABASE<\/strong> para monitorar todo o banco, ou <strong>ON SCHEMA<\/strong> para um schema espec\u00edfico. Para criar triggers de banco de dados, o usu\u00e1rio precisa do privil\u00e9gio <strong>ADMINISTER DATABASE TRIGGER<\/strong>, normalmente concedido ao <strong>SYSTEM<\/strong> ou ao <strong>SYS<\/strong>.<\/p>\n<p>Um caso de uso cl\u00e1ssico em seguran\u00e7a da informa\u00e7\u00e3o \u00e9 impedir que usu\u00e1rios executem <strong>DROP TABLE<\/strong> fora de uma janela de manuten\u00e7\u00e3o, ou registrar todos os comandos <strong>DDL<\/strong> executados no banco para posterior an\u00e1lise forense. Em projetos de implementa\u00e7\u00e3o da JRT Technology Solutions, nossos especialistas configuram triggers <strong>BEFORE DDL ON DATABASE<\/strong> para bloquear <strong>DROP<\/strong> e <strong>TRUNCATE<\/strong> em produ\u00e7\u00e3o, permitindo apenas durante janelas controladas por uma tabela de par\u00e2metros.<\/p>\n<p>Vamos criar uma trigger de <strong>DDL<\/strong> no schema atual para registrar, em uma tabela de log, todo comando <strong>CREATE<\/strong>, <strong>ALTER<\/strong>, <strong>DROP<\/strong> ou <strong>TRUNCATE<\/strong> executado pelo usu\u00e1rio. Para isso, primeiro criamos a tabela de log e a sequence. Em seguida, criamos a trigger com o evento <strong>BEFORE DDL ON SCHEMA<\/strong>. A fun\u00e7\u00e3o <strong>ORA_SYSEVENT<\/strong> retorna o tipo de evento, <strong>ORA_DICT_OBJ_NAME<\/strong> retorna o nome do objeto e <strong>ORA_DICT_OBJ_TYPE<\/strong> retorna o tipo.<\/p>\n<pre><code>-- =========================================================\n-- Conectar como SYSTEM para conceder privilegio de DDL trigger\n-- =========================================================\nGRANT ADMINISTER DATABASE TRIGGER TO hr;\n\n-- Conectar novamente como HR\n-- =========================================================\n-- Tabela de log para DDL\n-- =========================================================\nCREATE TABLE ddl_log (\n    log_id        NUMBER PRIMARY KEY,\n    ddl_event     VARCHAR2(30),\n    object_name   VARCHAR2(128),\n    object_type   VARCHAR2(30),\n    ddl_user      VARCHAR2(30),\n    ddl_date      DATE\n);\n\nCREATE SEQUENCE seq_ddl_log\n    START WITH 1\n    INCREMENT BY 1\n    NOCACHE;\n\n-- =========================================================\n-- Trigger BEFORE DDL ON SCHEMA para auditoria de DDL\n-- =========================================================\nCREATE OR REPLACE TRIGGER trg_audit_ddl_schema\n    BEFORE DDL ON SCHEMA\nBEGIN\n    INSERT INTO ddl_log (\n        log_id,\n        ddl_event,\n        object_name,\n        object_type,\n        ddl_user,\n        ddl_date\n    ) VALUES (\n        seq_ddl_log.NEXTVAL,\n        ORA_SYSEVENT,\n        ORA_DICT_OBJ_NAME,\n        ORA_DICT_OBJ_TYPE,\n        ORA_LOGIN_USER,\n        SYSDATE\n    );\nEND;\n\/<\/code><\/pre>\n<pre><code class=\"output\">Grant succeeded.\n\nTable created.\n\nSequence created.\n\nTrigger created.<\/code><\/pre>\n<p>A trigger <strong>TRG_AUDIT_DDL_SCHEMA<\/strong> ser\u00e1 executada antes de qualquer comando <strong>DDL<\/strong> no schema <strong>HR<\/strong>, gravando o evento, o objeto e o usu\u00e1rio respons\u00e1vel. Esse mecanismo \u00e9 poderoso para auditar altera\u00e7\u00f5es estruturais e detectar tentativas de modifica\u00e7\u00e3o n\u00e3o autorizada. Vamos testar criando e removendo uma tabela tempor\u00e1ria, e em seguida consultando a tabela <strong>DDL_LOG<\/strong>.<\/p>\n<pre><code>-- =========================================================\n-- Testar trigger DDL criando e dropar uma tabela temporaria\n-- =========================================================\nCREATE TABLE temp_test (\n    id NUMBER\n);\n\nDROP TABLE temp_test;<\/code><\/pre>\n<pre><code class=\"output\">Table created.\n\nTable dropped.<\/code><\/pre>\n<p>Agora, vamos verificar os registros na tabela <strong>DDL_LOG<\/strong>. A sa\u00edda deve mostrar dois eventos: <strong>CREATE<\/strong> e <strong>DROP<\/strong>, ambos relacionados ao objeto <strong>TEMP_TEST<\/strong>.<\/p>\n<pre><code>-- =========================================================\n-- Consultar auditoria de DDL\n-- =========================================================\nSET LINESIZE 200\nSET PAGESIZE 100\nCOLUMN ddl_event     FORMAT A20\nCOLUMN object_name   FORMAT A20\nCOLUMN object_type   FORMAT A20\nCOLUMN ddl_user      FORMAT A20\nCOLUMN ddl_date      FORMAT A20\n\nSELECT log_id,\n       ddl_event,\n       object_name,\n       object_type,\n       ddl_user,\n       TO_CHAR(ddl_date, 'YYYY-MM-DD HH24:MI:SS') AS ddl_date\nFROM   ddl_log\nORDER  BY log_id;<\/code><\/pre>\n<pre><code class=\"output\">    LOG_ID DDL_EVENT            OBJECT_NAME          OBJECT_TYPE          DDL_USER             DDL_DATE\n---------- -------------------- -------------------- -------------------- -------------------- --------------------\n         1 CREATE               TEMP_TEST            TABLE                HR                   2026-08-15 15:01:42\n         2 DROP                 TEMP_TEST            TABLE                HR                   2026-08-15 15:01:45\n\n2 rows selected.<\/code><\/pre>\n<p>A sa\u00edda comprova a efic\u00e1cia da trigger <strong>TRG_AUDIT_DDL_SCHEMA<\/strong>. Cada comando <strong>DDL<\/strong> foi capturado com o tipo exato do evento e o nome do objeto. Em ambientes cr\u00edticos, essa tabela de log pode ser enviada para um SIEM ou reposit\u00f3rio central de eventos, permitindo alertas em tempo real e an\u00e1lise de conformidade. Esse \u00e9 um padr\u00e3o que utilizamos em projetos de seguran\u00e7a de banco de dados na JRT Technology Solutions.<\/p>\n<h3>Verificando a Instala\u00e7\u00e3o \/ Testando a Configura\u00e7\u00e3o<\/h3>\n<p>Ap\u00f3s criar as <strong>Triggers PL\/SQL<\/strong> da aula, \u00e9 essencial verificar se todos os objetos foram compilados sem erros e se est\u00e3o ativos no dicion\u00e1rio de dados. O Oracle armazena metadados sobre triggers nas views <strong>USER_TRIGGERS<\/strong>, <strong>ALL_TRIGGERS<\/strong> e <strong>DBA_TRIGGERS<\/strong>. A view <strong>USER_TRIGGERS<\/strong> mostra as triggers do schema atual, com colunas importantes como <strong>TRIGGER_NAME<\/strong>, <\n\n\n<div style=\"margin:52px 0 40px;padding:36px 28px;background:linear-gradient(135deg,#0f172a 0%,#1a2744 100%);border:2px solid #25D366;border-radius:18px;text-align:center;box-shadow:0 4px 28px rgba(37,211,102,0.18)\">\n<p style=\"margin:0 0 10px;font-size:18px;color:#ffffff;font-weight:700;line-height:1.4\">Quer aprender na pr\u00e1tica com especialistas?<\/p>\n<p style=\"margin:0 0 28px;font-size:15px;color:#94a3b8;font-weight:400;line-height:1.6\">A JRT Technology Solutions oferece treinamentos e implementa\u00e7\u00e3o de Oracle SQL para equipes corporativas.<\/p>\n<p>  <a href=\"https:\/\/api.whatsapp.com\/send\/?phone=5521980606699&#038;text=Ol%C3%A1!%20Tenho%20interesse%20no%20treinamento%20de%20Oracle%20SQL.&#038;type=phone_number&#038;app_absent=0\"\n     target=\"_blank\" rel=\"noopener noreferrer\"\n     style=\"display:inline-flex;align-items:center;gap:12px;background:#25D366;color:#ffffff;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;font-size:16px;font-weight:700;padding:15px 32px;border-radius:100px;text-decoration:none;box-shadow:0 4px 16px rgba(37,211,102,0.45);letter-spacing:0.01em\"><br \/>\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"#ffffff\"><path d=\"M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z\"\/><\/svg><br \/>\n    Falar no WhatsApp<br \/>\n  <\/a>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>As Triggers PL\/SQL s\u00e3o um dos recursos mais poderosos do Oracle Database para garantir que regras de neg\u00f3cio sejam aplicadas de forma autom\u00e1tica, consistente e independente da aplica\u00e7\u00e3o que acessa os dados. Nesta aula voc\u00ea vai dominar a cria\u00e7\u00e3o, teste e manuten\u00e7\u00e3o dessas estruturas, entendendo exatamente quando e como o banco de dados executa cada &#8230; <a title=\"Aula 20: Triggers PL\/SQL \u2014 automa\u00e7\u00e3o de regras de neg\u00f3cio\" class=\"read-more\" href=\"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/\" aria-label=\"Read more about Aula 20: Triggers PL\/SQL \u2014 automa\u00e7\u00e3o de regras de neg\u00f3cio\">Ler mais<\/a><\/p>\n","protected":false},"author":1,"featured_media":2264,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"iawp_total_views":1,"footnotes":""},"categories":[75],"tags":[3316],"class_list":["post-2265","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","tag-oracle-sql-do-zero-ao-avancado-triggers-pl-sql-automacao-de-regras-de-negocio"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"As Triggers PL\/SQL s\u00e3o um dos recursos mais poderosos do Oracle Database para garantir que regras de neg\u00f3cio sejam aplicadas de forma autom\u00e1tica, consistente e independente da aplica\u00e7\u00e3o que acessa os dados. Nesta aula voc\u00ea vai dominar a cria\u00e7\u00e3o, teste e manuten\u00e7\u00e3o dessas estruturas, entendendo exatamente quando e como o banco de dados executa cada\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Thiago Paes Rodrigues\"\/>\n\t<meta name=\"google-site-verification\" content=\"QKPfpDCzHmzKyfFk5j1KZW3HhROYTPeqwBN5qcJ8qcg\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pt_BR\" \/>\n\t\t<meta property=\"og:site_name\" content=\"BLOG - JRT Technology Solutions - Um espa\u00e7o dedicado a explorar o universo da tecnologia de forma clara, pr\u00e1tica e atual. Aqui voc\u00ea encontra novidades, an\u00e1lises, tutoriais e reflex\u00f5es sobre inova\u00e7\u00e3o, intelig\u00eancia artificial, gadgets, programa\u00e7\u00e3o e tend\u00eancias digitais. Nosso objetivo \u00e9 simplificar o complexo, ajudar voc\u00ea a se manter atualizado e transformar conhecimento em pr\u00e1tica no seu dia a dia.\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Aula 20: Triggers PL\/SQL \u2014 automa\u00e7\u00e3o de regras de neg\u00f3cio - BLOG - JRT Technology Solutions\" \/>\n\t\t<meta property=\"og:description\" content=\"As Triggers PL\/SQL s\u00e3o um dos recursos mais poderosos do Oracle Database para garantir que regras de neg\u00f3cio sejam aplicadas de forma autom\u00e1tica, consistente e independente da aplica\u00e7\u00e3o que acessa os dados. Nesta aula voc\u00ea vai dominar a cria\u00e7\u00e3o, teste e manuten\u00e7\u00e3o dessas estruturas, entendendo exatamente quando e como o banco de dados executa cada\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/jrtx.com.br\/blog\/wp-content\/uploads\/2026\/03\/cropped-logo-mini.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/jrtx.com.br\/blog\/wp-content\/uploads\/2026\/03\/cropped-logo-mini.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"100\" \/>\n\t\t<meta property=\"og:image:height\" content=\"75\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-08-15T21:18:43+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-08-15T21:18:43+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/profile.php?id=61590814880509\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Aula 20: Triggers PL\/SQL \u2014 automa\u00e7\u00e3o de regras de neg\u00f3cio - BLOG - JRT Technology Solutions\" \/>\n\t\t<meta name=\"twitter:description\" content=\"As Triggers PL\/SQL s\u00e3o um dos recursos mais poderosos do Oracle Database para garantir que regras de neg\u00f3cio sejam aplicadas de forma autom\u00e1tica, consistente e independente da aplica\u00e7\u00e3o que acessa os dados. Nesta aula voc\u00ea vai dominar a cria\u00e7\u00e3o, teste e manuten\u00e7\u00e3o dessas estruturas, entendendo exatamente quando e como o banco de dados executa cada\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/jrtx.com.br\/blog\/wp-content\/uploads\/2026\/03\/cropped-logo-mini.jpg\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BlogPosting\",\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/2026\\\/08\\\/15\\\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\\\/#blogposting\",\"name\":\"Aula 20: Triggers PL\\\/SQL \\u2014 automa\\u00e7\\u00e3o de regras de neg\\u00f3cio - BLOG - JRT Technology Solutions\",\"headline\":\"Aula 20: Triggers PL\\\/SQL \\u2014 automa\\u00e7\\u00e3o de regras de neg\\u00f3cio\",\"author\":{\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/author\\\/thiago\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/ai-image-1786828716810.jpg\",\"width\":1440,\"height\":1024,\"caption\":\"Aula 20: Triggers PL\\\/SQL \\u2014 automa\\u00e7\\u00e3o de regras de neg\\u00f3cio\"},\"datePublished\":\"2026-08-15T18:18:43-03:00\",\"dateModified\":\"2026-08-15T18:18:43-03:00\",\"inLanguage\":\"pt-BR\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/2026\\\/08\\\/15\\\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/2026\\\/08\\\/15\\\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\\\/#webpage\"},\"articleSection\":\"DevOps, Oracle SQL \\u2014 Do Zero ao Avan\\u00e7ado: Triggers PL\\\/SQL \\u2014 automa\\u00e7\\u00e3o de regras de neg\\u00f3cio\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/2026\\\/08\\\/15\\\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/jrtx.com.br\\\/blog\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/category\\\/devops\\\/#listItem\",\"name\":\"DevOps\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/category\\\/devops\\\/#listItem\",\"position\":2,\"name\":\"DevOps\",\"item\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/category\\\/devops\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/2026\\\/08\\\/15\\\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\\\/#listItem\",\"name\":\"Aula 20: Triggers PL\\\/SQL \\u2014 automa\\u00e7\\u00e3o de regras de neg\\u00f3cio\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/2026\\\/08\\\/15\\\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\\\/#listItem\",\"position\":3,\"name\":\"Aula 20: Triggers PL\\\/SQL \\u2014 automa\\u00e7\\u00e3o de regras de neg\\u00f3cio\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/category\\\/devops\\\/#listItem\",\"name\":\"DevOps\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/#organization\",\"name\":\"JRT Technology Solutions | Tecnologia e Inova\\u00e7\\u00e3o para Empresas\",\"description\":\"Um espa\\u00e7o dedicado a explorar o universo da tecnologia de forma clara, pr\\u00e1tica e atual. Aqui voc\\u00ea encontra novidades, an\\u00e1lises, tutoriais e reflex\\u00f5es sobre inova\\u00e7\\u00e3o, intelig\\u00eancia artificial, gadgets, programa\\u00e7\\u00e3o e tend\\u00eancias digitais. Nosso objetivo \\u00e9 simplificar o complexo, ajudar voc\\u00ea a se manter atualizado e transformar conhecimento em pr\\u00e1tica no seu dia a dia.\",\"url\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/\",\"telephone\":\"+552138277513\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/03\\\/cropped-logo-mini.jpg\",\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/2026\\\/08\\\/15\\\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\\\/#organizationLogo\",\"width\":100,\"height\":75},\"image\":{\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/2026\\\/08\\\/15\\\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\\\/#organizationLogo\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/profile.php?id=61590814880509\",\"https:\\\/\\\/www.instagram.com\\\/jrtx.tech\\\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/author\\\/thiago\\\/#author\",\"url\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/author\\\/thiago\\\/\",\"name\":\"Thiago Paes Rodrigues\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/2026\\\/08\\\/15\\\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\\\/#authorImage\",\"url\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/cropped-foto-rascunho3-96x96.jpeg\",\"width\":96,\"height\":96,\"caption\":\"Thiago Paes Rodrigues\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/2026\\\/08\\\/15\\\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\\\/#webpage\",\"url\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/2026\\\/08\\\/15\\\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\\\/\",\"name\":\"Aula 20: Triggers PL\\\/SQL \\u2014 automa\\u00e7\\u00e3o de regras de neg\\u00f3cio - BLOG - JRT Technology Solutions\",\"description\":\"As Triggers PL\\\/SQL s\\u00e3o um dos recursos mais poderosos do Oracle Database para garantir que regras de neg\\u00f3cio sejam aplicadas de forma autom\\u00e1tica, consistente e independente da aplica\\u00e7\\u00e3o que acessa os dados. Nesta aula voc\\u00ea vai dominar a cria\\u00e7\\u00e3o, teste e manuten\\u00e7\\u00e3o dessas estruturas, entendendo exatamente quando e como o banco de dados executa cada\",\"inLanguage\":\"pt-BR\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/2026\\\/08\\\/15\\\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/author\\\/thiago\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/author\\\/thiago\\\/#author\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/ai-image-1786828716810.jpg\",\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/2026\\\/08\\\/15\\\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\\\/#mainImage\",\"width\":1440,\"height\":1024,\"caption\":\"Aula 20: Triggers PL\\\/SQL \\u2014 automa\\u00e7\\u00e3o de regras de neg\\u00f3cio\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/2026\\\/08\\\/15\\\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\\\/#mainImage\"},\"datePublished\":\"2026-08-15T18:18:43-03:00\",\"dateModified\":\"2026-08-15T18:18:43-03:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/\",\"name\":\"JRT Technology Solutions | Tecnologia e Inova\\u00e7\\u00e3o para Empresas\",\"alternateName\":\"JRT Technology Solutions | Tecnologia e Inova\\u00e7\\u00e3o para Empresas\",\"description\":\"Um espa\\u00e7o dedicado a explorar o universo da tecnologia de forma clara, pr\\u00e1tica e atual. Aqui voc\\u00ea encontra novidades, an\\u00e1lises, tutoriais e reflex\\u00f5es sobre inova\\u00e7\\u00e3o, intelig\\u00eancia artificial, gadgets, programa\\u00e7\\u00e3o e tend\\u00eancias digitais. Nosso objetivo \\u00e9 simplificar o complexo, ajudar voc\\u00ea a se manter atualizado e transformar conhecimento em pr\\u00e1tica no seu dia a dia.\",\"inLanguage\":\"pt-BR\",\"publisher\":{\"@id\":\"https:\\\/\\\/jrtx.com.br\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Aula 20: Triggers PL\/SQL \u2014 automa\u00e7\u00e3o de regras de neg\u00f3cio - BLOG - JRT Technology Solutions","description":"As Triggers PL\/SQL s\u00e3o um dos recursos mais poderosos do Oracle Database para garantir que regras de neg\u00f3cio sejam aplicadas de forma autom\u00e1tica, consistente e independente da aplica\u00e7\u00e3o que acessa os dados. Nesta aula voc\u00ea vai dominar a cria\u00e7\u00e3o, teste e manuten\u00e7\u00e3o dessas estruturas, entendendo exatamente quando e como o banco de dados executa cada","canonical_url":"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"google-site-verification":"QKPfpDCzHmzKyfFk5j1KZW3HhROYTPeqwBN5qcJ8qcg","miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BlogPosting","@id":"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/#blogposting","name":"Aula 20: Triggers PL\/SQL \u2014 automa\u00e7\u00e3o de regras de neg\u00f3cio - BLOG - JRT Technology Solutions","headline":"Aula 20: Triggers PL\/SQL \u2014 automa\u00e7\u00e3o de regras de neg\u00f3cio","author":{"@id":"https:\/\/jrtx.com.br\/blog\/author\/thiago\/#author"},"publisher":{"@id":"https:\/\/jrtx.com.br\/blog\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/jrtx.com.br\/blog\/wp-content\/uploads\/2026\/08\/ai-image-1786828716810.jpg","width":1440,"height":1024,"caption":"Aula 20: Triggers PL\/SQL \u2014 automa\u00e7\u00e3o de regras de neg\u00f3cio"},"datePublished":"2026-08-15T18:18:43-03:00","dateModified":"2026-08-15T18:18:43-03:00","inLanguage":"pt-BR","mainEntityOfPage":{"@id":"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/#webpage"},"isPartOf":{"@id":"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/#webpage"},"articleSection":"DevOps, Oracle SQL \u2014 Do Zero ao Avan\u00e7ado: Triggers PL\/SQL \u2014 automa\u00e7\u00e3o de regras de neg\u00f3cio"},{"@type":"BreadcrumbList","@id":"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/jrtx.com.br\/blog#listItem","position":1,"name":"Home","item":"https:\/\/jrtx.com.br\/blog","nextItem":{"@type":"ListItem","@id":"https:\/\/jrtx.com.br\/blog\/category\/devops\/#listItem","name":"DevOps"}},{"@type":"ListItem","@id":"https:\/\/jrtx.com.br\/blog\/category\/devops\/#listItem","position":2,"name":"DevOps","item":"https:\/\/jrtx.com.br\/blog\/category\/devops\/","nextItem":{"@type":"ListItem","@id":"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/#listItem","name":"Aula 20: Triggers PL\/SQL \u2014 automa\u00e7\u00e3o de regras de neg\u00f3cio"},"previousItem":{"@type":"ListItem","@id":"https:\/\/jrtx.com.br\/blog#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/#listItem","position":3,"name":"Aula 20: Triggers PL\/SQL \u2014 automa\u00e7\u00e3o de regras de neg\u00f3cio","previousItem":{"@type":"ListItem","@id":"https:\/\/jrtx.com.br\/blog\/category\/devops\/#listItem","name":"DevOps"}}]},{"@type":"Organization","@id":"https:\/\/jrtx.com.br\/blog\/#organization","name":"JRT Technology Solutions | Tecnologia e Inova\u00e7\u00e3o para Empresas","description":"Um espa\u00e7o dedicado a explorar o universo da tecnologia de forma clara, pr\u00e1tica e atual. Aqui voc\u00ea encontra novidades, an\u00e1lises, tutoriais e reflex\u00f5es sobre inova\u00e7\u00e3o, intelig\u00eancia artificial, gadgets, programa\u00e7\u00e3o e tend\u00eancias digitais. Nosso objetivo \u00e9 simplificar o complexo, ajudar voc\u00ea a se manter atualizado e transformar conhecimento em pr\u00e1tica no seu dia a dia.","url":"https:\/\/jrtx.com.br\/blog\/","telephone":"+552138277513","logo":{"@type":"ImageObject","url":"https:\/\/jrtx.com.br\/blog\/wp-content\/uploads\/2026\/03\/cropped-logo-mini.jpg","@id":"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/#organizationLogo","width":100,"height":75},"image":{"@id":"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/#organizationLogo"},"sameAs":["https:\/\/www.facebook.com\/profile.php?id=61590814880509","https:\/\/www.instagram.com\/jrtx.tech\/"]},{"@type":"Person","@id":"https:\/\/jrtx.com.br\/blog\/author\/thiago\/#author","url":"https:\/\/jrtx.com.br\/blog\/author\/thiago\/","name":"Thiago Paes Rodrigues","image":{"@type":"ImageObject","@id":"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/#authorImage","url":"https:\/\/jrtx.com.br\/blog\/wp-content\/uploads\/2026\/09\/cropped-foto-rascunho3-96x96.jpeg","width":96,"height":96,"caption":"Thiago Paes Rodrigues"}},{"@type":"WebPage","@id":"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/#webpage","url":"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/","name":"Aula 20: Triggers PL\/SQL \u2014 automa\u00e7\u00e3o de regras de neg\u00f3cio - BLOG - JRT Technology Solutions","description":"As Triggers PL\/SQL s\u00e3o um dos recursos mais poderosos do Oracle Database para garantir que regras de neg\u00f3cio sejam aplicadas de forma autom\u00e1tica, consistente e independente da aplica\u00e7\u00e3o que acessa os dados. Nesta aula voc\u00ea vai dominar a cria\u00e7\u00e3o, teste e manuten\u00e7\u00e3o dessas estruturas, entendendo exatamente quando e como o banco de dados executa cada","inLanguage":"pt-BR","isPartOf":{"@id":"https:\/\/jrtx.com.br\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/#breadcrumblist"},"author":{"@id":"https:\/\/jrtx.com.br\/blog\/author\/thiago\/#author"},"creator":{"@id":"https:\/\/jrtx.com.br\/blog\/author\/thiago\/#author"},"image":{"@type":"ImageObject","url":"https:\/\/jrtx.com.br\/blog\/wp-content\/uploads\/2026\/08\/ai-image-1786828716810.jpg","@id":"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/#mainImage","width":1440,"height":1024,"caption":"Aula 20: Triggers PL\/SQL \u2014 automa\u00e7\u00e3o de regras de neg\u00f3cio"},"primaryImageOfPage":{"@id":"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/#mainImage"},"datePublished":"2026-08-15T18:18:43-03:00","dateModified":"2026-08-15T18:18:43-03:00"},{"@type":"WebSite","@id":"https:\/\/jrtx.com.br\/blog\/#website","url":"https:\/\/jrtx.com.br\/blog\/","name":"JRT Technology Solutions | Tecnologia e Inova\u00e7\u00e3o para Empresas","alternateName":"JRT Technology Solutions | Tecnologia e Inova\u00e7\u00e3o para Empresas","description":"Um espa\u00e7o dedicado a explorar o universo da tecnologia de forma clara, pr\u00e1tica e atual. Aqui voc\u00ea encontra novidades, an\u00e1lises, tutoriais e reflex\u00f5es sobre inova\u00e7\u00e3o, intelig\u00eancia artificial, gadgets, programa\u00e7\u00e3o e tend\u00eancias digitais. Nosso objetivo \u00e9 simplificar o complexo, ajudar voc\u00ea a se manter atualizado e transformar conhecimento em pr\u00e1tica no seu dia a dia.","inLanguage":"pt-BR","publisher":{"@id":"https:\/\/jrtx.com.br\/blog\/#organization"}}]},"og:locale":"pt_BR","og:site_name":"BLOG - JRT Technology Solutions - Um espa\u00e7o dedicado a explorar o universo da tecnologia de forma clara, pr\u00e1tica e atual. Aqui voc\u00ea encontra novidades, an\u00e1lises, tutoriais e reflex\u00f5es sobre inova\u00e7\u00e3o, intelig\u00eancia artificial, gadgets, programa\u00e7\u00e3o e tend\u00eancias digitais. Nosso objetivo \u00e9 simplificar o complexo, ajudar voc\u00ea a se manter atualizado e transformar conhecimento em pr\u00e1tica no seu dia a dia.","og:type":"article","og:title":"Aula 20: Triggers PL\/SQL \u2014 automa\u00e7\u00e3o de regras de neg\u00f3cio - BLOG - JRT Technology Solutions","og:description":"As Triggers PL\/SQL s\u00e3o um dos recursos mais poderosos do Oracle Database para garantir que regras de neg\u00f3cio sejam aplicadas de forma autom\u00e1tica, consistente e independente da aplica\u00e7\u00e3o que acessa os dados. Nesta aula voc\u00ea vai dominar a cria\u00e7\u00e3o, teste e manuten\u00e7\u00e3o dessas estruturas, entendendo exatamente quando e como o banco de dados executa cada","og:url":"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/","og:image":"https:\/\/jrtx.com.br\/blog\/wp-content\/uploads\/2026\/03\/cropped-logo-mini.jpg","og:image:secure_url":"https:\/\/jrtx.com.br\/blog\/wp-content\/uploads\/2026\/03\/cropped-logo-mini.jpg","og:image:width":100,"og:image:height":75,"article:published_time":"2026-08-15T21:18:43+00:00","article:modified_time":"2026-08-15T21:18:43+00:00","article:publisher":"https:\/\/www.facebook.com\/profile.php?id=61590814880509","twitter:card":"summary_large_image","twitter:title":"Aula 20: Triggers PL\/SQL \u2014 automa\u00e7\u00e3o de regras de neg\u00f3cio - BLOG - JRT Technology Solutions","twitter:description":"As Triggers PL\/SQL s\u00e3o um dos recursos mais poderosos do Oracle Database para garantir que regras de neg\u00f3cio sejam aplicadas de forma autom\u00e1tica, consistente e independente da aplica\u00e7\u00e3o que acessa os dados. Nesta aula voc\u00ea vai dominar a cria\u00e7\u00e3o, teste e manuten\u00e7\u00e3o dessas estruturas, entendendo exatamente quando e como o banco de dados executa cada","twitter:image":"https:\/\/jrtx.com.br\/blog\/wp-content\/uploads\/2026\/03\/cropped-logo-mini.jpg"},"aioseo_meta_data":{"post_id":"2265","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_custom_url":null,"og_image_custom_fields":null,"og_image_url":null,"og_image_width":null,"og_image_height":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_image_url":null,"twitter_title":null,"twitter_description":null,"schema_type":"default","schema_type_options":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"limit_modified_date":false,"ai":null,"breadcrumb_settings":null,"seo_analyzer_scan_date":null,"created":"2026-08-15 21:19:07","updated":"2026-08-15 21:19:07","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/jrtx.com.br\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/jrtx.com.br\/blog\/category\/devops\/\" title=\"DevOps\">DevOps<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tAula 20: Triggers PL\/SQL \u2014 automa\u00e7\u00e3o de regras de neg\u00f3cio\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/jrtx.com.br\/blog"},{"label":"DevOps","link":"https:\/\/jrtx.com.br\/blog\/category\/devops\/"},{"label":"Aula 20: Triggers PL\/SQL \u2014 automa\u00e7\u00e3o de regras de neg\u00f3cio","link":"https:\/\/jrtx.com.br\/blog\/2026\/08\/15\/aula-20-triggers-plsql-automacao-de-regras-de-negocio\/"}],"_links":{"self":[{"href":"https:\/\/jrtx.com.br\/blog\/wp-json\/wp\/v2\/posts\/2265","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jrtx.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jrtx.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jrtx.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jrtx.com.br\/blog\/wp-json\/wp\/v2\/comments?post=2265"}],"version-history":[{"count":0,"href":"https:\/\/jrtx.com.br\/blog\/wp-json\/wp\/v2\/posts\/2265\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jrtx.com.br\/blog\/wp-json\/wp\/v2\/media\/2264"}],"wp:attachment":[{"href":"https:\/\/jrtx.com.br\/blog\/wp-json\/wp\/v2\/media?parent=2265"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jrtx.com.br\/blog\/wp-json\/wp\/v2\/categories?post=2265"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jrtx.com.br\/blog\/wp-json\/wp\/v2\/tags?post=2265"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}