Quelques problèmes sans ordre particulier.
Tout d'abord, dans le corps d'un déclencheur au niveau de la ligne, vous devez utiliser :new
et :old
pour référencer les nouveaux et anciens enregistrements. Le premier côlon est nécessaire. Donc, votre WHERE
clause devrait être
WHERE PROJECTID = :new.PROJECTID
Deuxièmement, si vous exécutez votre CREATE TRIGGER
dans SQL*Plus, vous pouvez obtenir une liste des erreurs et des avertissements en utilisant le SHOW ERRORS
commande, c'est-à-dire
SQL> show errors
Vous pouvez également interroger le DBA_ERRORS
table (ou ALL_ERRORS
ou USER_ERRORS
en fonction de votre niveau de privilège) mais ce n'est pas quelque chose auquel vous devez normalement recourir.
Troisièmement, en supposant que les erreurs de syntaxe soient corrigées, vous obtiendrez un mutating erreur de tableau
si vous utilisez cette logique. Un déclencheur au niveau de la ligne sur la table A (TPM_TRAININGPLAN
dans ce cas) ne peut pas interroger la table A car la table peut être dans un état incohérent. Vous pouvez contourner cela, comme le montre Tim dans son article, en créant un package avec une collection, en initialisant cette collection dans un déclencheur d'instruction avant, en remplissant les données de la collection dans un déclencheur au niveau de la ligne, puis en traitant les lignes modifiées dans un déclencheur d'instruction après. C'est une quantité décente de complexité à ajouter au système, cependant, puisque vous devrez gérer plusieurs objets différents.
En règle générale, vous feriez mieux d'implémenter cette logique dans le cadre de l'API que vous utilisez pour manipuler le TPM_TRAININGPLAN
table. S'il s'agit d'une procédure stockée, il est beaucoup plus logique de mettre la logique à jour TPM_PROJECT
dans cette procédure stockée plutôt que de la mettre dans un déclencheur. Il est notoirement pénible d'essayer de déboguer une application qui a beaucoup de logique intégrée dans les déclencheurs car cela rend très difficile pour les développeurs de suivre exactement quelles opérations sont effectuées. Vous pouvez également supprimer le TRAININGDELIVERYSTART
colonne de TPM_PROJECT
table et calculez simplement la date de début minimale au moment de l'exécution.
Quatrièmement, si votre déclencheur se déclenche lors d'insertions, de mises à jour et de suppressions, vous ne pouvez pas simplement référencer :new
valeurs. :new
est valide pour les insertions et les mises à jour, mais il sera NULL si vous effectuez une suppression. :old
est valide pour les suppressions et les mises à jour mais va être NULL si vous faites une insertion. Cela signifie que vous devez probablement avoir une logique du type (référence à la solution de package 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;