web-dev-qa-db-fra.com

SQL Server: déclencher comment lire la valeur pour insérer, mettre à jour, supprimer

J'ai le déclencheur dans une table et je voudrais lire la valeur UserId lorsqu'une ligne est insérée, mise à jour ou supprimée. Comment faire ça? Le code ci-dessous ne fonctionne pas, j'obtiens une erreur sur UPDATED

ALTER TRIGGER [dbo].[UpdateUserCreditsLeft] 
   ON  [dbo].[Order]
   AFTER INSERT,UPDATE,DELETE
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    DECLARE 
    @UserId INT,

    SELECT @UserId = INSERTED.UserId FROM INSERTED, DELETED

    UPDATE dbo.[User] SET CreditsLeft = CreditsLeft - 1 WHERE Id = @UserId
END
17
Tomas

Veuillez noter que inserted, deleted signifie la même chose que inserted CROSS JOIN deleted et donne chaque combinaison de chaque ligne. Je doute que c'est ce que tu veux.

Quelque chose comme ça peut vous aider à démarrer ...

SELECT
  CASE WHEN inserted.primaryKey IS NULL THEN 'This is a delete'
       WHEN  deleted.primaryKey IS NULL THEN 'This is an insert'
                                        ELSE 'This is an update'
  END  as Action,
  *
FROM
  inserted
FULL OUTER JOIN
  deleted
    ON inserted.primaryKey = deleted.primaryKey


Selon ce que vous voulez faire, vous référencez ensuite le tableau qui vous intéresse avec inserted.userID ou deleted.userID, etc.


Enfin, sachez que inserted et deleted sont des tables et peuvent (et font) contenir plusieurs enregistrements.

Si vous insérez 10 enregistrements à la fois, la table inserted contiendra TOUS les 10 enregistrements. Il en va de même pour les suppressions et la table deleted. Et les deux tableaux dans le cas d'une mise à jour.


MODIFIER Examplee Déclenchement après modification des OP.

ALTER TRIGGER [dbo].[UpdateUserCreditsLeft] 
  ON  [dbo].[Order]
  AFTER INSERT,UPDATE,DELETE
AS 
BEGIN

  -- SET NOCOUNT ON added to prevent extra result sets from
  -- interfering with SELECT statements.
  SET NOCOUNT ON;

  UPDATE
    User
  SET
    CreditsLeft = CASE WHEN inserted.UserID IS NULL THEN <new value for a  DELETE>
                       WHEN  deleted.UserID IS NULL THEN <new value for an INSERT>
                                                    ELSE <new value for an UPDATE>
                  END
  FROM
    User
  INNER JOIN
    (
      inserted
    FULL OUTER JOIN
      deleted
        ON inserted.UserID = deleted.UserID  -- This assumes UserID is the PK on UpdateUserCreditsLeft
    )
      ON User.UserID = COALESCE(inserted.UserID, deleted.UserID)

END


Si la clé primaire de UpdateUserCreditsLeft est autre que UserID, utilisez-la à la place dans la FULL OUTER JOIN.

29
MatBailie

Il n'y a pas de table dynamique updated. Il n'y a que inserted et deleted. Sur une commande UPDATE, les anciennes données sont stockées dans la table dynamique deleted et les nouvelles valeurs sont stockées dans la table dynamique inserted.

Considérez un UPDATE comme un DELETE/INSERT combinaison.

24
user596075