Domanda

Sto cercando di capire che ho bisogno di usare qui:. Eliminato, inserito o aggiornato

in fondo.

Ho bisogno di scrivere alcuni dati nella tabella storia, quando la tabella principale è aggiornato, e solo se lo stato cambia da qualcosa a uno in sospeso o attivo.

Questo è quello che ho adesso:

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]

così voglio i nuovi dati di rimanere nella tabella principale, la tabella la storia per essere aggiornato con ciò che viene sovrascritto ... In questo momento è solo copie le stesse informazioni sopra. così dopo l'aggiornamento, entrambi i miei tabelle hanno gli stessi dati.

È stato utile?

Soluzione

È necessario utilizzare le tabelle sia il inserted e deleted insieme per verificare la presenza di record che:
1. esisteva già (per verificare che non è un inserto)
2. esiste ancora (per controllare che non è una cancellazione)
3. Il campo Stato cambiato

È inoltre necessario assicurarsi che fare che in un approccio basato insieme, come per la risposta di marc_s, i trigger non sono processi singolo record.

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')
  • = inserito i nuovi valori
  • soppresso = i vecchi valori

Altri suggerimenti

Non ci sono solo le tabelle pseudo Inserted e Deleted - non c'è Updated.

Per un UPDATE, Inserted contiene i nuovi valori (dopo l'aggiornamento), mentre Deleted contiene i vecchi valori prima dell'aggiornamento.

Anche essere consapevoli che i trigger è sparato una volta per partita - non una sola volta per ogni riga. Così entrambe le tabelle pseudo saranno potenzialmente contengono più righe ! Non dare per scontato una singola riga per poi assegnarlo a una variabile - questo

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

non riuscirà se si dispone di più righe! Hai bisogno di scrivere i trigger in modo tale che lavorano con più righe in Inserted e Deleted!

Aggiornamento: Sì - ci un modo molto migliore per scrivere questo:

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')

In sostanza:

  • specificare esplicitamente le colonne che si desidera inserire - sia nella dichiarazione INSERT così come la dichiarazione SELECT il recupero dei dati da inserire - per evitare sorprese

  • Crea un INNER JOIN tra Inserted e Deleted pseudo-tabelle per ottenere tutte le righe che sono stati aggiornati

  • specificare tutte le altre condizioni (diversi codici di stato, ecc) nella clausola WHERE del SELECT

Questa soluzione funziona per i lotti di file in fase di aggiornamento - non mancherà su un aggiornamento multi-fila ....

Non v'è alcun tavolo updated, siete alla ricerca di inserted.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top