Algunos números sin ningún orden en particular.
Primero, en el cuerpo de un activador de nivel de fila, debe usar :new
y :old
para hacer referencia a los registros nuevos y antiguos. Los dos puntos principales son necesarios. Así que tu WHERE
la cláusula tendría que ser
WHERE PROJECTID = :new.PROJECTID
En segundo lugar, si está ejecutando su CREATE TRIGGER
en SQL*Plus, puede obtener una lista de errores y advertencias usando SHOW ERRORS
comando, es decir,
SQL> show errors
También puede consultar el DBA_ERRORS
tabla (o ALL_ERRORS
o USER_ERRORS
dependiendo de su nivel de privilegio), pero eso no es algo a lo que normalmente deba recurrir.
En tercer lugar, suponiendo que se corrijan los errores de sintaxis, obtendrá un mutante error de tabla
si usas esta lógica. Un activador de nivel de fila en la tabla A (TPM_TRAININGPLAN
en este caso) no puede consultar la tabla A porque la tabla puede estar en un estado inconsistente. Puede solucionar eso, como muestra Tim en su artículo, creando un paquete con una colección, inicializando esa colección en un disparador de declaración anterior, completando los datos en la colección en un disparador de nivel de fila y luego procesando las filas modificadas en un disparador de declaración posterior. Sin embargo, esa es una cantidad decente de complejidad para agregar al sistema, ya que tendrá que administrar múltiples objetos diferentes.
En general, sería mejor implementar esta lógica como parte de cualquier API que use para manipular el TPM_TRAININGPLAN
mesa. Si ese es un procedimiento almacenado, tiene mucho más sentido poner la lógica para actualizar TPM_PROJECT
en ese procedimiento almacenado en lugar de ponerlo en un disparador. Es notoriamente doloroso tratar de depurar una aplicación que tiene mucha lógica incrustada en los disparadores porque eso hace que sea muy difícil para los desarrolladores seguir exactamente qué operaciones se están realizando. Como alternativa, puede eliminar el TRAININGDELIVERYSTART
columna de TPM_PROJECT
tabla y simplemente calcule la fecha de inicio mínima en tiempo de ejecución.
En cuarto lugar, si su activador se activa en inserciones, actualizaciones y eliminaciones, no puede simplemente hacer referencia a :new
valores. :new
es válido para inserciones y actualizaciones, pero será NULL si está realizando una eliminación. :old
es válido para eliminaciones y actualizaciones, pero será NULL si está haciendo una inserción. Eso significa que probablemente necesite tener una lógica similar a (haciendo referencia a la solución del paquete de Tim)
BEGIN
IF inserting
THEN
trigger_api.tab1_row_change(p_id => :new.projectid, p_action => 'INSERT');
ELSIF updating
THEN
trigger_api.tab1_row_change(p_id => :new.projectid, p_action => 'UPDATE');
ELSIF deleting
THEN
trigger_api.tab1_row_change(p_id => :old.projectid, p_action => 'DELETE');
END IF;
END;