Oracle Disparador PL/SQL: en lugar de tipos compuestos

โšก Resumen inteligente

Los disparadores PL/SQL son programas almacenados que Oracle El motor se activa automรกticamente cuando se produce una operaciรณn DML, DDL o un evento de base de datos. Mantiene la integridad de los datos, aplica reglas y admite auditorรญas, e incluye tipos BEFORE, AFTER, INSTEAD OF y compuestos.

  • ๐Ÿ”” Definiciรณn del disparador: Un disparador es un programa almacenado. Oracle El motor se activa automรกticamente ante un evento DML, DDL o de base de datos especรญfico.
  • ๐ŸŽฏ Tipos de Activadores: Los disparadores se clasifican por momento (ANTES, DESPUร‰S, EN LUGAR DE), nivel (SENTENCIA, FILA) y evento (DML, DDL, BASE DE DATOS).
  • ๐Ÿ” :NUEVO y :ANTIGUO: Los disparadores a nivel de fila utilizan las clรกusulas :NEW y :OLD para leer los valores de las columnas antes y despuรฉs de la instrucciรณn DML.
  • ๐ŸชŸ EN LUGAR DE Gatillo: Un disparador INSTEAD OF hace que una vista compleja que de otro modo no se podrรญa actualizar sea modificable actuando sobre sus tablas base.
  • ๐Ÿงฉ Disparador compuesto: Un disparador compuesto combina acciones para los cuatro puntos de sincronizaciรณn dentro de un mismo cuerpo de disparo.
  • ๐Ÿค– Asistencia de IA: Asistentes de IA como GitHub Copilot redactan ANTES, DESPUร‰S, EN LUGAR DE y activadores compuestos a partir de un comentario.

Oracle Disparadores PL/SQL, incluidos los tipos de disparadores INSTEAD OF y compuestos.

ยฟQuรฉ es el disparador en PL/SQL?

Los disparadores se almacenan PL / SQL programas que son activados por el Oracle motor automรกticamente cuando Declaraciones DML Las operaciones como insertar, actualizar y eliminar se ejecutan en la tabla, o cuando ocurren ciertos eventos. El cรณdigo que se ejecuta en el caso de un disparador se puede definir segรบn los requisitos. Se puede elegir el evento que activarรก el disparador y el momento de su ejecuciรณn. El propรณsito de un disparador es mantener la integridad de la informaciรณn en la base de datos.

Beneficios de los desencadenantes

A continuaciรณn se presentan los beneficios de los desencadenantes.

  • Generar algunos valores de columna derivados automรกticamente
  • Hacer cumplir la integridad referencial
  • Registro de eventos y almacenamiento de informaciรณn sobre el acceso a la tabla
  • Revisiรณn de cuentas
  • Syncreplicaciรณn cronosa de tablas
  • Imposiciรณn de autorizaciones de seguridad
  • Prevenciรณn de transacciones no vรกlidas

Tipos de desencadenantes en Oracle

Los desencadenantes se pueden clasificar segรบn los siguientes parรกmetros.

Clasificaciรณn basada en el momento

  • ANTES del disparador: Se activa antes de que ocurra el evento especificado.
  • DESPUร‰S del disparador: Se activa despuรฉs de que haya ocurrido el evento especificado.
  • EN LUGAR DE Gatillo: Un tipo especial. Aprenderรกs mรกs en los siguientes temas. (Solo para DML)

Clasificaciรณn basada en el nivel

  • Disparador de nivel de DECLARACIร“N: Se activa una sola vez para la instrucciรณn de evento especificada.
  • Disparador a nivel de fila: Se activa para cada registro afectado por el evento especificado. (Solo para DML)

Clasificaciรณn basada en el evento

  • Disparador DML: Se activa cuando se especifica el evento DML (INSERTAR/ACTUALIZAR/ELIMINAR).
  • Disparador DDL: Se activa cuando se especifica el evento DDL (CREATE/ALTER).
  • Disparador de BASE DE DATOS: Se activa cuando se especifica el evento de la base de datos (LOGON/LOGOFF/STARTUP/SHUTDOWN).

Por lo tanto, cada disparador es una combinaciรณn de los parรกmetros mencionados anteriormente.

Cรณmo crear un disparador

A continuaciรณn se muestra la sintaxis para crear un disparador. La captura de pantalla que aparece a continuaciรณn muestra esta sintaxis de creaciรณn de disparadores. Oracle.

Sintaxis de creaciรณn de disparadores con opciones ANTES, DESPUร‰S e INSTEAD OF en Oracle PL / SQL

CREATE [ OR REPLACE ] TRIGGER <trigger_name> 

[BEFORE | AFTER | INSTEAD OF ]

[INSERT | UPDATE | DELETE......]

ON<name of underlying object>

[FOR EACH ROW] 

[WHEN<condition for trigger to get execute> ]

DECLARE
<Declaration part>
BEGIN
<Execution part> 
EXCEPTION
<Exception handling part> 
END;

Explicaciรณn de sintaxis:

  • La sintaxis anterior muestra las diferentes declaraciones opcionales que estรกn presentes en la creaciรณn del disparador.
  • ANTES/DESPUร‰S especificarรก los momentos en que se produce el evento.
  • INSERTAR/ACTUALIZAR/INICIAR SESIร“N/CREAR/etc. especificarรก el evento para el cual se debe activar el disparador.
  • La clรกusula ON especificarรก el objeto sobre el cual el evento mencionado anteriormente es vรกlido. Por ejemplo, este serรก el nombre de la tabla sobre la cual puede ocurrir el evento DML en el caso de un disparador DML.
  • El comando โ€œFOR EACH ROWโ€ especificarรก el disparador a nivel de fila.
  • La clรกusula WHEN especificarรก la condiciรณn adicional en la que debe activarse el disparador.
  • La parte de declaraciรณn, la parte de ejecuciรณn y la parte de manejo de excepciones son las mismas que las de los demรกs. bloques PL/SQL. La parte de la declaraciรณn y la manejo de excepciones Las partes son opcionales.

:NUEVO y :VIEJO Clรกusula

En un disparador de nivel de fila, el disparador se activa para cada fila relacionada. Y a veces es necesario conocer el valor antes y despuรฉs de la declaraciรณn DML.

Oracle Se han proporcionado dos clรกusulas en el disparador a nivel de fila para almacenar estos valores. Podemos usar estas clรกusulas para referirnos a los valores antiguos y nuevos dentro del cuerpo del disparador.

  • :NUEVO โ€“ Almacena un nuevo valor para las columnas de la tabla/vista base durante la ejecuciรณn del disparador.
  • :VIEJO โ€“ Conserva el valor anterior de las columnas de la tabla/vista base durante la ejecuciรณn del disparador.

Esta clรกusula debe utilizarse en funciรณn del evento DML. La siguiente tabla especifica quรฉ clรกusula es vรกlida para cada instrucciรณn DML (INSERT/UPDATE/DELETE).

INSERT ACTUALIZAR BORRAR
:NUEVO VรLIDO VรLIDO NO VรLIDO. No hay ningรบn valor nuevo en el caso de eliminaciรณn.
:VIEJO NO VรLIDO. No hay ningรบn valor anterior en el caso de inserciรณn. VรLIDO VรLIDO

EN LUGAR DE Gatillo

Un disparador "INSTEAD OF" es un tipo especial de disparador. Se utiliza รบnicamente en disparadores DML. Se usa cuando se va a producir algรบn evento DML en una vista compleja.

Consideremos un ejemplo en el que una vista se crea a partir de tres tablas base. Cuando se ejecuta cualquier operaciรณn DML sobre esta vista, esta se invalida porque los datos provienen de tres tablas diferentes. En este caso, se utiliza un disparador INSTEAD OF. Este disparador modifica directamente las tablas base en lugar de la vista para el evento en cuestiรณn.

Ejemplo 1: En este ejemplo, vamos a crear una vista compleja a partir de dos tablas base, donde Tabla_1 es la tabla de empleados y Tabla_2 es โ€‹โ€‹la tabla de departamentos.

A continuaciรณn, veremos cรณmo se utiliza el disparador INSTEAD OF para actualizar los detalles de ubicaciรณn en esta vista compleja. Tambiรฉn veremos la utilidad de :NEW y :OLD en los disparadores. El ejemplo se realiza siguiendo estos pasos:

  • Paso 1: Creaciรณn de las tablas 'emp' y 'dept' con las columnas correspondientes.
  • Paso 2: Rellenar las tablas con valores de muestra.
  • Paso 3: Creaciรณn de una vista para las tablas creadas anteriormente.
  • Paso 4: Actualizaciรณn de la vista antes del disparador INSTEAD OF
  • Paso 5: Creaciรณn del disparador INSTEAD OF
  • Paso 6: Actualizaciรณn de la vista despuรฉs del desencadenador INSTEAD OF

Paso 1) Crear las tablas 'emp' y 'dept' con las columnas apropiadas.

La captura de pantalla a continuaciรณn muestra la creaciรณn de las tablas base 'emp' y 'dept' en Oracle.

Creaciรณn de las tablas base emp y dept en Oracle para el ejemplo del disparador INSTEAD OF

CREATE TABLE emp(
emp_no NUMBER,
emp_name VARCHAR2(50),
salary NUMBER,
manager VARCHAR2(50),
dept_no NUMBER);
/

CREATE TABLE dept(
Dept_no NUMBER,
Dept_name VARCHAR2(50),
LOCATION VARCHAR2(50));
/

Code Explicaciรณn

  • Code lรญneas 1-7: Creaciรณn de la tabla 'emp'.
  • Code lรญneas 8-12: Creaciรณn de la tabla 'depto'.

Salida:

Table Created

Paso 2) Ahora que hemos creado las tablas, las rellenaremos con valores de ejemplo.

La captura de pantalla que aparece a continuaciรณn muestra las filas de ejemplo que se insertan en las tablas 'dept' y 'emp'.

Insertar filas de muestra de departamento y empleado en Oracle PL / SQL

BEGIN
INSERT INTO DEPT VALUES(10,'HR','USA');
INSERT INTO DEPT VALUES(20,'SALES','UK');
INSERT INTO DEPT VALUES(30,'FINANCIAL','JAPAN');
COMMIT;
END;
/

BEGIN
INSERT INTO EMP VALUES(1000,'XXX',15000,'AAA',30);
INSERT INTO EMP VALUES(1001,'YYY',18000,'AAA',20) ;
INSERT INTO EMP VALUES(1002,'ZZZ',20000,'AAA',10);
COMMIT;
END;
/

Code Explicaciรณn

  • Code lรญneas 13-19: Insertando datos en la tabla 'dept'.
  • Code lรญneas 20-26: Insertando datos en la tabla 'emp'.

Salida:

PL/SQL procedure completed

Paso 3) Creaciรณn de una vista para las tablas creadas anteriormente.

La siguiente captura de pantalla muestra cรณmo se crea la vista compleja y cรณmo se realiza la consulta.

Creaciรณn y consulta de la vista compleja guru99_emp_view que une emp y dept.

CREATE VIEW guru99_emp_view(
Employee_name,dept_name,location) AS
SELECT emp.emp_name,dept.dept_name,dept.location
FROM emp,dept
WHERE emp.dept_no=dept.dept_no;
/
SELECT * FROM guru99_emp_view;

Code Explicaciรณn

  • Code lรญneas 27-32: Creaciรณn de la vista 'guru99_emp_view'.
  • Code lรญnea 33: Consultando guru99_emp_view.

Salida:

View created
NOMBRE DE EMPLEADO DEPTO_NOMBRE UBICACIร“N
ZZZ HR USA
YYY OFERTAS UK
XXX FINANCIERA JAPร“N

Paso 4) Actualizaciรณn de la vista antes del disparador INSTEAD OF.

La captura de pantalla que aparece a continuaciรณn muestra el intento de actualizaciรณn de la vista compleja y el error resultante.

Actualizaciรณn sobre el fallo de la vista compleja con ORA-01779 antes del disparador INSTEAD OF

BEGIN
UPDATE guru99_emp_view SET location='FRANCE' WHERE employee_name='XXX';
COMMIT;
END;
/

Code Explicaciรณn

  • Code lรญneas 34-38: Actualizar la ubicaciรณn de โ€œXXXโ€ a 'FRANCIA'. Se produjo una excepciรณn porque las instrucciones DML no estรกn permitidas directamente en la vista compleja.

Salida:

ORA-01779: cannot modify a column which maps to a non key-preserved table

ORA-06512: at line 2

Paso 5) Para evitar el error que se produjo al actualizar la vista en el paso anterior, en este paso vamos a utilizar un disparador "INSTEAD OF".

La captura de pantalla que aparece a continuaciรณn muestra la creaciรณn del disparador INSTEAD OF.

Crear el disparador guru99_view_modify_trg EN LUGAR DE en la vista compleja

CREATE TRIGGER guru99_view_modify_trg
INSTEAD OF UPDATE
ON guru99_emp_view
FOR EACH ROW
BEGIN
UPDATE dept
SET location=:new.location
WHERE dept_name=:old.dept_name;
END;
/

Code Explicaciรณn

  • Code lรญnea 39: Creaciรณn del disparador INSTEAD OF para el evento 'UPDATE' en la vista 'guru99_emp_view' a nivel de fila. Contiene la instrucciรณn de actualizaciรณn para actualizar la ubicaciรณn en la tabla base 'dept'.
  • Code lรญnea 44: La instrucciรณn de actualizaciรณn utiliza ':NEW' y ':OLD' para encontrar el valor de las columnas antes y despuรฉs de la actualizaciรณn.

Salida:

Trigger Created

Paso 6) Actualizaciรณn de la vista tras el disparador INSTEAD OF. Ahora no aparecerรก el error, ya que el disparador INSTEAD OF gestionarรก la actualizaciรณn de esta vista compleja. Al ejecutarse el cรณdigo, la ubicaciรณn del empleado XXX se actualizarรก de ยซJapรณnยป a ยซFranciaยป.

La captura de pantalla que aparece a continuaciรณn muestra la actualizaciรณn exitosa a travรฉs del activador INSTEAD OF y la vista actualizada.

Actualizaciรณn de vista exitosa a travรฉs del activador INSTEAD OF que muestra la ubicaciรณn FRANCIA

BEGIN
UPDATE guru99_emp_view SET location='FRANCE' WHERE employee_name='XXX';
COMMIT;
END;
/
SELECT * FROM guru99_emp_view;

Code Explicaciรณn:

  • Code lรญneas 49-53: Actualizaciรณn de la ubicaciรณn de โ€œXXXโ€ a 'FRANCIA'. La operaciรณn se realizรณ correctamente porque el disparador 'INSTEAD OF' detuvo la instrucciรณn de actualizaciรณn real en la vista y realizรณ la actualizaciรณn de la tabla base.
  • Code lรญnea 55: Verificando el registro actualizado.

Salida:

PL/SQL procedure successfully completed
NOMBRE DE EMPLEADO DEPTO_NOMBRE UBICACIร“N
ZZZ HR USA
YYY OFERTAS UK
XXX FINANCIERA FRANCIA

Gatillo compuesto

El disparador compuesto es un disparador que permite especificar acciones para cada uno de los cuatro puntos de temporizaciรณn en un รบnico cuerpo de disparador. Los cuatro puntos de temporizaciรณn diferentes que admite son los siguientes.

  • ANTES DE LA DECLARACIร“N โ€“ nivel
  • ANTES DE LA FILA โ€“ nivel
  • DESPUร‰S DE LA FILA โ€“ nivel
  • DECLARACIร“N POSTERIOR โ€“ nivel

Permite combinar acciones con diferentes tiempos de activaciรณn en un mismo disparador.

La captura de pantalla que aparece a continuaciรณn muestra la sintaxis del disparador compuesto con sus cuatro secciones de temporizaciรณn.

Sintaxis de disparador compuesto que muestra las secciones de sentencia BEFORE y AFTER y de temporizaciรณn de filas.

CREATE [ OR REPLACE ] TRIGGER <trigger_name>
FOR
[INSERT | UPDATE | DELETE.......]
ON <name of underlying object>
<Declarative part>
BEFORE STATEMENT IS
BEGIN
<Execution part>;
END BEFORE STATEMENT;

BEFORE EACH ROW IS
BEGIN
<Execution part>;
END EACH ROW;

AFTER EACH ROW IS
BEGIN
<Execution part>;
END AFTER EACH ROW;

AFTER STATEMENT IS
BEGIN
<Execution part>;
END AFTER STATEMENT;
END;

Explicaciรณn de sintaxis:

  • La sintaxis anterior muestra la creaciรณn de un disparador 'COMPOUND'.
  • La secciรณn declarativa es comรบn a todos los bloques de ejecuciรณn en el cuerpo del disparador.
  • Estos cuatro bloques de temporizaciรณn pueden estar en cualquier secuencia. No es obligatorio tener los cuatro bloques. Podemos crear un disparador COMPUESTO solo para los bloques de temporizaciรณn necesarios.

Ejemplo 1: En este ejemplo, vamos a crear un disparador para rellenar automรกticamente la columna de salario con el valor predeterminado de 5000.

La captura de pantalla que aparece a continuaciรณn muestra un ejemplo del disparador compuesto y su resultado.

El activador compuesto rellena automรกticamente la columna de salario con un valor predeterminado de 5000.

CREATE TRIGGER emp_trig
FOR INSERT
ON emp
COMPOUND TRIGGER
BEFORE EACH ROW IS
BEGIN
:new.salary:=5000;
END BEFORE EACH ROW;
END emp_trig;
/
BEGIN
INSERT INTO EMP VALUES(1004,'CCC',15000,'AAA',30);
COMMIT;
END;
/
SELECT * FROM emp WHERE emp_no=1004;

Code Explicaciรณn:

  • Code lรญneas 2-10: Creaciรณn del disparador compuesto. Se crea para el nivel de tiempo ANTES DE LA FILA para rellenar el salario con el valor predeterminado 5000. Esto cambiarรก el salario al valor predeterminado '5000' antes de insertar el registro en la tabla.
  • Code lรญneas 11-14: Inserta el registro en la tabla 'emp'.
  • Code lรญnea 16: Verificando el registro insertado.

Salida:

Trigger created

PL/SQL procedure successfully completed.
EMP_NOMBRE EMP_NO SALARIO GENERAL DEPTO_NO
CCC 1004 5000 AAA 30

Habilitar y deshabilitar desencadenadores

Los disparadores se pueden habilitar o deshabilitar. Para habilitar o deshabilitar un disparador, se debe especificar una instrucciรณn ALTER (DDL) para dicho disparador.

A continuaciรณn se muestra la sintaxis para habilitar/deshabilitar los disparadores.

ALTER TRIGGER <trigger_name> [ENABLE|DISABLE];
ALTER TABLE <table_name> [ENABLE|DISABLE] ALL TRIGGERS;

Explicaciรณn de sintaxis:

  • La primera sintaxis muestra cรณmo habilitar/deshabilitar un รบnico disparador.
  • La segunda declaraciรณn muestra cรณmo habilitar/deshabilitar todos los activadores en una tabla en particular.

Preguntas Frecuentes

El error ORA-04091 (mutaciรณn de tabla) se produce cuando un disparador a nivel de fila intenta consultar o modificar la misma tabla que lo activรณ. Para evitarlo, utilice un disparador compuesto, un disparador a nivel de instrucciรณn o almacene las filas en una colecciรณn de paquetes.

Un disparador se activa automรกticamente cuando ocurre un evento DML, DDL o de base de datos, no toma parรกmetros y no devuelve nada. procedimiento almacenado Se ejecuta รบnicamente cuando se le llama explรญcitamente, acepta parรกmetros y puede devolver valores.

Utilice la instrucciรณn DROP TRIGGER trigger_name para eliminar un disparador de forma permanente. A diferencia de la deshabilitaciรณn, que mantiene el disparador pero impide que se active, dropping Elimina la definiciรณn por completo, por lo que deberรก volver a crearla si necesita la lรณgica nuevamente.

Consulta las vistas del diccionario de datos USER_TRIGGERS para tus propios desencadenadores o ALL_TRIGGERS para todos los desencadenadores a los que tengas acceso. Estas vistas muestran el nombre del desencadenador, el tipo, el evento que lo activa, el objeto base y el estado, lo que te ayuda a auditar los desencadenadores existentes.

No directamente, porque el disparador comparte la instrucciรณn de disparo. transaccionalPara confirmar de forma independiente, declare el disparador, o un procedimiento al que llama, con PRAGMA AUTONOMOUS_TRANSACTION, que ejecuta el trabajo en una transacciรณn separada que se confirma por sรญ misma.

Antes Oracle En la versiรณn 11g, no se garantizaba el orden de los disparadores del mismo tipo. A partir de la versiรณn 11g, la clรกusula FOLLOWS en la instrucciรณn CREATE TRIGGER permite especificar que un disparador se ejecute despuรฉs de otro, lo que proporciona un orden de ejecuciรณn determinista.

Sรญ. Copiloto de GitHub borradores ANTES, DESPUร‰S, EN LUGAR DE y activadores compuestos, incluidas referencias :NEW y :OLD, desde un comentario. RevRevise los tiempos, la condiciรณn CUANDO y los riesgos de mutaciรณn de la tabla antes de implementar el disparador generado.

Los asistentes de IA analizan los disparadores en busca de riesgos relacionados con tablas en constante mutaciรณn, manejo deficiente de :NEW o :OLD, activaciรณn recursiva y lรณgica compleja que ralentiza las operaciones DML. Este anรกlisis mediante aprendizaje automรกtico identifica los disparadores vulnerables y sugiere reescrituras a nivel de sentencia o de cรณdigo compuesto antes de que el cรณdigo llegue a producciรณn.

Resumir este post con: