curseur dans un déclencheur
J'ai une TABLE existante postn_matrix
qui contient une liste des employés et un décompte de leur reee. des postes dans l'organisation.
Chaque fois qu'un poste d'un utilisateur est ajouté ou supprimé, le comte est reflétée dans le tableau thro' ce déclencheur (VIA mise à JOUR)
Maintenant, si il y a un nouvel utilisateur, il ne sera pas avoir une entrée dans postn_matrix
, j'ai donc insérer un nouveau record pour lui/elle (VIA un INSERT). Cela doit être introduit à partir de la TABLE de BASE.
La mise à jour semble fonctionner très bien, mais je ne suis pas en mesure de mettre dans un nouvel utilisateur dans la table.
J'ai essayé de traiter ce cas avec un curseur. Mais il n'en a pas été de tout aider encore.
J'espère que certains d'experts pourrait me montrer la lumière.. :). toutes les autres suggestions en plus de l'aide d'un curseur sera très appréciée
CREATE OR REPLACE TRIGGER TRIG1
BEFORE INSERT OR DELETE ON (BASETABLE)
FOR EACH ROW
DECLARE
cursor c1 is
select person_id
from postn_matrix;
v_temp varchar2(15);
BEGIN
IF INSERTING THEN
open c1;
LOOP
fetch c1 into v_temp;
if v_temp!=:new.person_id THEN
insert into POSTN_MATRIX (PERSON_ID)
VALUES (:new.PERSON_ID);
else
UPDATE POSTN_MATRIX
//this is working fine ;
END IF;
end loop;
close c1;
END
/
- Je ne comprends pas. Si il y a un nouvel enregistrement dans BASETABLE et vous savez déjà qu'il n'y a pas d'enregistrement dans POSTN_MATRIX, pourquoi voudriez-vous faire une boucle par un curseur sur POSTN_MATRIX? Il suffit d'insérer un nouvel enregistrement.
- S'il vous plaît obtenir un livre de base sur SQL et de le lire. Vous avez besoin d'un curseur pour ce faire, et en outre votre SQL ne devrait normalement pas avoir
if then
déclarations en elle. SQL est un jeu de langage orienté. voir codeproject.com/Articles/10144/SQL-as-a-set-oriented-language
Vous devez vous connecter pour publier un commentaire.
À cause de la boucle (qui manque d'une clause de sortie - nous espérons que vous avez tout simplement perdu que traduire cela dans une question), vous allez tenter d'insérer un enregistrement dans
pstn_matrix
pour chaque enregistrer le curseur retourne, s'il existe une correspondance:new.person_id
ou pas; et si il y a match, vous pourrez aussi faire leupdate
. Qui n'est probablement pas ce que vous voulez, et vous pouvez obtenir d'une violation de contrainte parmi d'autres choses. Vous aussi ne sont pas de la définition de votre champ de compteur - si ce n'est pas les valeurs null alors que l'erreur. Mais vous n'avez pas dit ce que les erreurs, le cas échéant, vous obtenez.Si vous devez le faire par le biais d'un déclencheur ensuite, vous pouvez vérifier si il y a une ligne pour la nouvelle personne à tous:
... ou utiliser
merge
.Mais je n'aime pas ce modèle, et que vous êtes en train de configurer le potentiel pour les écarts entre les données avec les modifications concurrentes à la table de base. En essayant de maintenir un nombre comme ce n'est pas forcément aussi simple qu'il y paraît.
J'avais préfèrent généralement de faire de cette vue, qui vous permettra de toujours être à jour et n'a pas besoin de le déclencheur de compliquer les choses:
Bien sûr, j'ai peut-être mal interprété ou de simplifier à l'extrême ce que votre table de base(s) et ce que vous avez besoin
postn_matrix
pour. Il semble un peu triviale encore qu'une vue de l'. Si vous avez séparéperson
etperson_position
de tables, de dire, puis vous pouvez ajouter une jointure externe de voir des gens avec aucun des postes::new.person_id
. Si il juste n'aselect person_id into v_temp
puis si il n'y avait pas d'enregistrements existants, vous obtiendrezORA-01403
, et si il n'y avait plus d'un, vous obtiendrezORA-02112
. À l'aide demax()
signifie que vous obtenez toujours exactement une ligne; si il ya un certain nombre d'enregistrements correspondants, il aura l'ID, sinon il sera nulle. Vous pouvez également faire decount()
et vérifier nulle ou non nulle lignes trouvé si vous trouvez que plus claire.