Je vais commencer par un exemple très simple: deux tables, toutes les deux avec le même schéma, clusterisées sur PK, mais dont l'une a un INSTEAD OF UPDATE
déclencheur:
CREATE TABLE Standard
(
PK UNIQUEIDENTIFIER PRIMARY KEY CLUSTERED,
V INT NOT NULL
)
GO
CREATE TABLE InsteadOf
(
PK UNIQUEIDENTIFIER PRIMARY KEY CLUSTERED,
V INT NOT NULL
)
GO
INSERT Standard (PK, V) VALUES ('1E58B555-B073-471E-B576-4B09C8E18976', 0)
INSERT InsteadOf (PK, V) VALUES ('1E58B555-B073-471E-B576-4B09C8E18976', 0)
GO
CREATE TRIGGER TR_InsteadOf_Update ON InsteadOf INSTEAD OF UPDATE
AS
BEGIN
DECLARE @PK UNIQUEIDENTIFIER
DECLARE @V INT
DECLARE @cursor CURSOR
SET @cursor = CURSOR FOR SELECT PK, V FROM Inserted
OPEN @cursor
FETCH NEXT FROM @cursor INTO @PK, @V
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE InsteadOf SET
V = @V
WHERE PK = @PK
FETCH NEXT FROM @cursor INTO @PK, @V
END
CLOSE @cursor
DEALLOCATE @cursor
END
GO
Si j'affiche le plan de requête pour une mise à jour par rapport à la table standard, j'obtiens la mise à jour attendue de l'index sécurisé:
UPDATE Standard SET
V = 1
WHERE PK = '1E58B555-B073-471E-B576-4B09C8E18976'
Cependant, si j'effectue une mise à jour similaire sur la table avec le déclencheur, j'obtiens ce qui semble être une insertion d'index en cluster, ainsi que la mise à jour de l'index en cluster:
UPDATE InsteadOf SET
V = 1
WHERE PK = '1E58B555-B073-471E-B576-4B09C8E18976'
Pourquoi est-ce? Je peux voir la mise à jour d'index cluster que j'attendais plus tard dans ce plan de requête (requête # 4), mais pourquoi est-ce que j'obtiens cet insert supplémentaire à la requête # 1?