¿Por qué una ACTUALIZACIÓN en una tabla con un desencadenador INSTEAD OF UPDATE parece realizar una inserción de índice agrupado, así como una actualización de índice agrupado?

10

Comenzaré con un ejemplo muy simple: dos tablas, ambas con el mismo esquema, agrupadas en PK, pero una de las cuales tiene un INSTEAD OF UPDATEactivador:

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 veo el plan de consulta para una actualización con respecto a la tabla estándar, obtengo la actualización de índice en clúster esperada:

UPDATE Standard SET
    V = 1
    WHERE PK = '1E58B555-B073-471E-B576-4B09C8E18976'

ingrese la descripción de la imagen aquí

Sin embargo, si realizo una actualización similar en la tabla con el activador, obtengo lo que parece ser una inserción de índice agrupado, así como la actualización de índice agrupado:

UPDATE InsteadOf SET
    V = 1
    WHERE PK = '1E58B555-B073-471E-B576-4B09C8E18976'

ingrese la descripción de la imagen aquí

¿Por qué es esto? Puedo ver la actualización del índice agrupado que esperaba más adelante en este plan de consulta (consulta # 4), pero ¿por qué obtengo esta inserción adicional en la consulta # 1?

stusmith
fuente

Respuestas:

10

Un INSTEAD OFdisparador almacena una copia de las filas que se verían afectadas en una tabla de trabajo oculta *. Este es el Insertar índice agrupado que ves. El cuerpo del disparador lee de esta tabla de trabajo * y cualquier cambio de datos en el disparador usa el operador 'normal' (Actualización de índice agrupado en su ejemplo).


* El procesador de consultas renombra internamente la tabla de trabajo cuando construye la forma visible del usuario del plan de ejecución. Al escribir en él, se renombra a la tabla base de destino, al leer, se renombra como insertedo deletedmás o menos como la gente esperaría ver en un disparador.

Para obtener más detalles, consulte mi artículo Cosas interesantes sobre los desencadenantes INSTEAD OF .

Paul White 9
fuente