web-dev-qa-db-fra.com

SQL Server 2008 - Aide à l'écriture d'un déclencheur INSERT simple

C'est avec Microsoft SQL Server 2008.

J'ai 2 tables, Employee et EmployeeResult et j'essaie d'écrire un déclencheur INSERT simple sur EmployeeResult qui le fait - chaque fois qu'un INSERT est effectué dans EmployeeResult, comme:

(Jack, 200, Ventes) (Jane, 300, Marketing) (John, 400, Ingénierie)

Il doit rechercher les paires d'entrées Nom, Département, telles que

(Jack, Ventes), (Jane, Marketing), (John, Ingénierie)

dans la table Employé, et si un tel employé n'existe pas, vous devez l'insérer dans la table Employé.

Ce que j'ai c'est avec des inconnues sur la façon de réparer les "???":

CREATE TRIGGER trig_Update_Employee
ON [EmployeeResult]
FOR INSERT
AS
IF EXISTS (SELECT COUNT(*) FROM Employee WHERE ???)
  BEGIN
   INSERT INTO [Employee] (Name, Department) VALUES (???, ???)
  END

S'il vous plaît aider, merci d'avance

Schéma:

Employee
--------
Name, varchar(50)
Department, varchar (50)

EmployeeResult
--------------
Name, varchar(50)
Salary, int
Department, varchar (50)
22
Anonymous Coward

Vous souhaitez profiter de la table logique insérée qui est disponible dans le contexte d'un déclencheur. Il correspond au schéma de la table en cours d'insertion et inclut la ou les lignes qui seront insérées (dans un déclencheur de mise à jour, vous avez accès aux inséré et supprimé tableaux logiques qui représentent respectivement les données nouvelles et originales.)

Donc, pour insérer des paires Employé/Département qui n'existent pas actuellement, vous pouvez essayer quelque chose comme ceci.

CREATE TRIGGER trig_Update_Employee
ON [EmployeeResult]
FOR INSERT
AS
Begin
    Insert into Employee (Name, Department) 
    Select Distinct i.Name, i.Department 
    from Inserted i
    Left Join Employee e
    on i.Name = e.Name and i.Department = e.Department
    where e.Name is null
End
67
cmsjr

cmsjr avait la bonne solution. Je voulais juste souligner deux ou trois choses pour votre futur développement de déclencheur. Si vous utilisez l'instruction values ​​dans un insert dans un déclencheur, il est fort possible que vous fassiez la mauvaise chose. Les déclencheurs se déclenchent une fois pour chaque lot d'enregistrements insérés, supprimés ou mis à jour. Donc, si dix enregistrements ont été insérés dans un lot, le déclencheur se déclenche une fois. Si vous vous référez aux données dans les variables insérées ou supprimées et en utilisant la clause values, vous n'obtiendrez que les données pour l'un de ces enregistrements. Cela provoque des problèmes d'intégrité des données. Vous pouvez résoudre ce problème en utilisant un insert basé sur un ensemble comme cmsjr le montre ci-dessus ou en utilisant un curseur. Ne choisissez jamais le chemin du curseur. Un curseur dans un déclencheur est un problème qui attend de se produire car ils sont lents et peuvent bien verrouiller votre table pendant des heures. J'ai supprimé un curseur d'un déclencheur une fois et amélioré le processus d'importation de 40 minutes à 45 secondes.

Vous pensez peut-être que personne ne va jamais ajouter plusieurs enregistrements, mais cela se produit plus fréquemment que la plupart des personnes ne faisant pas partie de la base de données ne le pensent. N'écrivez pas de déclencheur qui ne fonctionnera pas dans toutes les conditions d'insertion, de mise à jour et de suppression possibles. Personne ne va utiliser la méthode d'un enregistrement à la fois lorsqu'il doit importer 1000000 d'enregistrements de ventes cibles d'un nouveau client ou mettre à jour tous les prix de 10% ou supprimer tous les enregistrements d'un fournisseur dont vous ne vendez plus les produits.

27
HLGEM

vérifiez ce code:

CREATE TRIGGER trig_Update_Employee ON [EmployeeResult] FOR INSERT AS Begin   
    Insert into Employee (Name, Department)  
    Select Distinct i.Name, i.Department   
        from Inserted i
        Left Join Employee e on i.Name = e.Name and i.Department = e.Department
        where e.Name is null
End
2
deepak