2009-10-20 8 views
0

J'utilise SQL Server 2000. Je suis en train d'écrire un déclencheur qui est exécuté lorsqu'un champ Applicant.AppStatusRowIDL'écriture d'un déclencheur complexe

Tableau des candidats est liée à la table Emplacement, table Company & Table AppStatus.

Mon problème est de créer les jointures dans ma requête.

Lorsque Applicant.AppStatusRowID est mis à jour, je veux obtenir les valeurs de Applicant.AppStatusRowID, Applicant.FirstName, Applicant.Lastname, Location.LocNumber, Location.LocationName, Company.CompanyCode, AppStatus.DisplayText

le joint serait:

Select * from Applicant A 
Inner Join AppStatus ast on ast.RowID = a.AppStatusRowID 
Inner Join Location l on l.RowID = a.LocationRowID 
Inner Join Company c on c.RowID = l.CompanyRowID 

Ce doit être inséré dans une table de vérification (les champs sont ApplicantID, LastName, FirstName, date, heure, entreprise, numéro de emplacement, emplacement Nom, StatusDisposition, utilisateur)

Mon problème est la requête pour la jointure interne ...

+0

J'espère que vous ne mettez pas à jour une clé primaire, c'est une mauvaise idée. –

+0

si vous mettez à jour la clé comment pourriez-vous vous joindre aux autres tables? _ast.RowID = a.AppStatusRowID_ –

Répondre

3

D'abord, nous allons vous présenter les pseudotables insérés et supprimés qui ne sont disponibles que dans les triggers. Inséré a de nouvelles valeurs et a supprimé les anciennes valeurs ou les enregistrements en cours de suppression.

Vous ne voulez pas insérer tous les enregistrements dans votre table d'audit uniquement ceux insérés.

donc d'insérer dans une table de vérification que vous voudrez peut-être quelque chose comme dans le code de déclenchement:

insert Myaudittable (<insert field list here>) 
Select <insert field list here> from Inserted i 
Inner Join AppStatus ast on ast.RowID = i.AppStatusRowID 
Inner Join Location l on l.RowID = i.LocationRowID 
Inner Join Company c on c.RowID = l.CompanyRowID 

Personnellement, j'ajouter des colonnes pour les valeurs anciennes et nouvelles, une colonne pour le type de changement et que la date du changement et de ce que l'utilisateur a fait le changement, mais je suis sûr que vous avez votre propre exigence à suivre.

Suggérez-nous de lire à propos des déclencheurs dans les livres en ligne car ils peuvent être difficiles à résoudre.

Voici une façon de tester et de déboguer le déclencheur que j'utilise souvent. Tout d'abord, je crée les noms des tables temporaires #delted et #inserted qui ont l'importance de la table sur laquelle je vais mettre le trigger. Ensuite, j'écris le code pour les utiliser à la place des tables supprimées ou insérées. Ce que je peux regarder les choses comme je vais et assurez-vous que tout est correct avant de changer le code à un déclencheur. Exemple ci-dessous avec votre code ajouté et modifié légèrement:

Create table #inserted(Rowid int, lastname varchar(100), firstname varchar(100), appstatusRowid int) 
    Insert #inserted 
    select 1, 'Jones', 'Ed', 30 
    union all 
    select 2, 'Smith', 'Betty', 20 

    Create table #deleted (Rowid int, lastname varchar(100), firstname varchar(100), appstatusRowid int) 
    Insert #deleted 
    select 1, 'Jones', 'Ed', 10 
    union all 
    select 2, 'Smith', 'Betty', 20 

--CREATE TRIGGER tri_UpdateAppDisp ON dbo.Test_App 
--For Update 
--AS 
--If Update(appstatusrowid) 
IF exists (select i.appstatusRowid from #inserted i join #deleted d on i.rowid = d.rowid 
      Where d.appstatusrowid <> i.appstatusrowid) 
BEGIN 
--Insert AppDisp(AppID, LastName, FirstName, [DateTime],Company,Location,LocationName, StatusDisp,[Username]) 
Select d.Rowid,d.LastName, d.FirstName, getDate(),C.CompanyCode, 
l.locnum,l.locname, ast.Displaytext, SUSER_SNAME()+' '+User 
From #deleted d 
Join #inserted i on i.rowid = d.rowid 
--From deleted d 
--Join inserted i on i.rowid = d.rowid 
Inner join Test_App a with (nolock) on a.RowID = d.rowid 
inner join location l with (nolock) on l.rowid = d.Locationrowid 
inner join appstatus ast with (nolock) on ast.rowid = d.appstatusrowid 
inner join company c with (nolock) on c.rowid = l.CompanyRowid 
Where d.appstatusrowid <> i.appstatusrowid) 
end 

Une fois que vous obtenez les données pour la sélection correcte, alors il est facile de décommenter le code de déclenchement et la ligne d'insertion et le changement #DELETED ou #inserted à supprimé ou inséré.

Vous remarquerez que j'avais deux enregistrements dans les tables temporaires, dont l'un répondait à votre condition et l'autre non. Cela vous permet de tester plusieurs mises à jour d'enregistrements ainsi que des résultats qui répondent à la condition et d'autres qui ne le sont pas. Tous les déclencheurs doivent être écrits pour gérer plusieurs enregistrements car ils ne sont pas déclenchés ligne par ligne mais par lot.

+0

Malheureusement, je suis limité sur la créativité que je peux obtenir. J'ai besoin que les enregistrements soient insérés dans la table d'audit une fois que quelqu'un met à jour le AppStatusRowID dans la table Applicant. D'où le besoin d'un déclencheur. Mais je n'arrive pas à faire fonctionner ma requête de jointures. – DotNetRookie

+0

Ensuite, vous devrez probablement utiliser l'ancienne valeur de AppStatusRowID, c'est-à-dire se référer à DELETED (au lieu de Inserted dans le code ci-dessus). – Thorsten

+0

J'ai essayé le DELETED, mais ne fonctionnait toujours pas pour moi. La table de destination n'est pas mise à jour. – DotNetRookie