Pregunta

Estoy tratando de averiguar qué necesito usar aquí: eliminado, insertado o actualizado.

básicamente.

Necesito escribir algunos datos en la tabla del historial, cuando se actualiza la tabla principal, y solo si el estado cambia de algo a pendiente o activo.

Esto es lo que tengo ahora:

ALTER TRIGGER [dbo].[trg_SourceHistory]  ON [dbo].[tblSource]
FOR UPDATE AS  
    DECLARE @statusOldValue char(1) 
    DECLARE @statusNewValue char(1)

    SELECT @statusOldValue = statusCode FROM deleted 
    SELECT @statusNewValue= statusCode FROM updated

    IF (@statusOldValue <> @statusNewValue) AND 
       (@statusOldValue = 'P' or @statusOldValue = 'A')
    BEGIN TRY
       INSERT * INTO tblHistoryTable)  
           select * from [DELETED]

Por lo tanto, quiero que los nuevos datos permanezcan en la tabla principal, la tabla de historial se actualiza con lo que se está sobrescribiendo ... en este momento simplemente copia la misma información. Entonces, después de la actualización, ambas tablas tienen los mismos datos.

¿Fue útil?

Solución

Necesitas usar ambos inserted y deleted tablas juntas para verificar los registros que:
1. Ya existió (para verificar que no sea un inserto)
2. Todavía existe (para verificar que no sea un eliminación)
3. El campo de estado cambió

También debe asegurarse de hacerlo en un enfoque basado en un conjunto, según la respuesta de Marc_S, los desencadenantes no son procesos de registro únicos.

INSERT INTO
  tblHistoryTable
SELECT
  deleted.*
FROM
  inserted
INNER JOIN
  deleted
    ON inserted.PrimaryKey = deleted.PrimaryKey
WHERE
  inserted.StatusCode <> deleted.StatusCode
  AND (inserted.StatusCode = 'P' OR inserted.StatusCode = 'A')
  • insertado = los nuevos valores
  • eliminado = los valores antiguos

Otros consejos

Solo hay el Inserted y Deleted pseudo mesas - no hay Updated.

Por un UPDATE, Inserted contiene los nuevos valores (después de la actualización) mientras Deleted Contiene los valores antiguos antes de la actualización.

También ser consciente que se disparan los desencadenantes Una vez por lote - Ni una sola vez para cada fila. Entonces ambas pseudo mesas contendrán potencialmente múltiples filas! No asuma una sola fila y asigne esto a una variable, esta

SELECT @statusOldValue = statusCode FROM deleted 
SELECT @statusNewValue= statusCode FROM updated

fallará ¡Si tienes varias filas! Necesitas escribir tus desencadenantes de tal manera que trabajan múltiples filas en Inserted y Deleted !

Actualizar: si ahí ES Una manera mucho mejor de escribir esto:

ALTER TRIGGER [dbo].[trg_SourceHistory]  ON [dbo].[tblSource]
FOR UPDATE 
AS  
   INSERT INTO dbo.tblHistoryTable(Col1, Col2, Col3, ...., ColN)
      SELECT Col1, COl2, Col3, ..... ColN
        FROM Deleted d
        INNER JOIN Inserted i ON i.PrimaryKey = d.PrimaryKey
        WHERE i.statusCode <> d.statusCode
          AND d.statusCode IN ('A', 'P')

Básicamente:

  • Especifique explícitamente las columnas que desea insertar, ambas en el INSERT declaración y el SELECT Declaración recuperando los datos para insertar: para evitar cualquier sorpresa desagradable

  • crear un INNER JOIN Entre Inserted y Deleted Pseudo-tablas para obtener todas las filas que se actualizaron

  • especificar todas las demás condiciones (diferentes códigos de estado, etc.) en el WHERE cláusula del SELECT

Esta solución funciona para lotes de filas que se actualizan: no fallará en una actualización de múltiples filas ...

No hay updated mesa, estás buscando inserted.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top