0
votes

SQL: déclencheur pour empêcher l'insertion d'une ligne dans une table basée sur une condition

J'ai les tables suivantes:

CREATE OR REPLACE TRIGGER review_check_validity
AFTER INSERT ON review
FOR EACH ROW
BEGIN
    SELECT testing_start
    FROM testing
    WHERE driver_no = :new.driver_no;

    SELECT vehicle_id
    FROM testing
    WHERE driver_no = :new.driver_no;

    IF :new.review_date < testing_end THEN
    raise_application_error(-20000, 'Review date cannot be before 
    testing end date');

    END IF;

    IF :new.vehicle_id != vehicle_id THEN
    raise_application_error(-20000, 'Driver has never driven this 
    vehicle');

    END IF;
END;
/


3 Réponses :


0
votes

Je pense que vous devriez avoir une clause dans vos extratures sélectionnées. J'ai ajouté des notes dans votre requête pour essayer de vous aider à le nettoyer.

CREATE OR REPLACE TRIGGER review_check_validity
AFTER INSERT ON review
FOR EACH ROW

-- Need to declare variables for usage in your SELECT fetches.
DECLARE
var_revdate number; -- or date, if applicable
var_revvehi number; -- or varchar(n), if applicable

BEGIN
    -- In here you should have an INTO clause to assign your date parameter into 
    -- the predefined variable. As well, you need to ensure this fetch will provide
    -- only one row.

    SELECT testing_start INTO var_revdate -- why are you fetching "testing_start"?
        FROM testing
            WHERE driver_no = :new.driver_no;

    -- Same case, it can only retrieve one row. If you need to do more than one row, 
    -- you may need to use a BULK & a LOOP.

    SELECT vehicle_id INTO var_vehicid
        FROM testing
            WHERE driver_no = :new.driver_no;

    IF :new.review_date < testing_end THEN
    raise_application_error(-20000, 'Review date cannot be before testing end date');

    END IF;

    IF :new.vehicle_id != var_vehicid THEN
    raise_application_error(-20000, 'Driver has never driven this vehicle');

    END IF;
END;
/


0 commentaires

1
votes

Je réorganiserais la logique ici et:

  1. Vérifiez si le pilote a testé le véhicule, puis
  2. Vérifiez si l'examen est tenté avant la date de fin de test pour le véhicule (quelque chose que vous avez laissé de côté).

    dans Oracle Pl / SQL, qui inclut le code de déclenchement, vous ne pouvez pas simplement SELECT . Vous devez SELECT dans une variable. Ensuite, vous pouvez utiliser la variable dans votre logique.

    tout aussi important, lorsque vous Sélectionnez dans une variable La requête ne peut renvoyer qu'un seul résultat. Plusieurs lignes déclencheront l'erreur que vous avez rencontrée. xxx

    Enfin, votre structure de table permet de multiples tests du même véhicule par le même pilote. Si elle devrait laisser cela, alors la table doit être un lien vers la table Test par test_id plutôt que pilote_no et véhicule_id .


0 commentaires

0
votes

Il y a quelques erreurs dans votre code:

  • dans pl / sql Select Les requêtes doivent avoir un dans la clause où les données récupérées à partir de la requête SELECT sont stockées dans certaines variables. - Cette partie manque dans votre code

  • Vous recherchez dans la table de test avec le seul driverno , qui vous donnera tous les enregistrements de ce driverno (tous les véhicules testés par cela < code> driveno ). Vous devez inclure véhiculeID avec driverno pour aller chercher les détails des tests pertinents à l'examen actuel.

    Donc, votre code de déclenchement peut être ré-écrit comme suit: xxx

    acclamations !!


0 commentaires