2013-01-24 11 views
11

Ho una tabella contenente due colonne not nullCreated e Updated.Attivazione dopo l'inserimento nella colonna non nulla

ho scritto corrispondente trigger

ALTER TRIGGER [dbo].[tr_category_inserted] ON [dbo].[Category] 
AFTER INSERT 
AS 
BEGIN 
    UPDATE Category 
    SET Created = GETDATE(), Updated = GETDATE() 
    FROM inserted 
    WHERE Category.ID = inserted.ID; 
END 

e

ALTER TRIGGER [dbo].[tr_category_updated] ON [dbo].[Category] 
AFTER UPDATE 
AS 
BEGIN 
    UPDATE Category 
    SET Updated = GETDATE() 
    FROM inserted 
     inner join [dbo].[Category] c on c.ID = inserted.ID 
END 

ma se io sono l'inserimento di una nuova riga ottengo un errore

Impossibile inserire il valore NULL nella colonna 'Creato ', tabella ' Categoria '; la colonna non consente null. INSERT fallisce.

comando Inserisci:

INSERT INTO [Category]([Name], [ShowInMenu], [Deleted]) 
    VALUES ('category1', 0, 0) 

Come posso scrivere tali trigger senza un'impostazione per queste colonne per permettere nulla?

+8

Se si desidera aggiornare 'date' automaticamente su' insert', suggerisco di usare il vincolo 'default' invece di' triggers' – DON

+3

Si verifica un errore perché il trigger funziona solo dopo l'inserimento e non è possibile inserire i valori della colonna 'Creato' e' Aggiornato' al momento dell'inserimento. – TechDo

+1

Come dice già il trigger, il trigger si attiva ** DOPO ** l'inserimento è successo - ma è necessario fornire un ** valore ** su 'INSERT' per qualsiasi colonna' NOT NULL'. Quindi è necessario scrivere un trigger 'INSTEAD OF INSERT' per impostare il valore iniziale di tali colonne -o molto più facilmente: basta definire un vincolo' DEFAULT (GETDATE()) 'su quella colonna in modo che venga automaticamente riempito su' INSERT '.... –

risposta

3

Modificare la tabella come questa:

ALTER TABLE yourTable MODIFY COLUMN updated timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; 
ALTER TABLE yourTable MODIFY COLUMN created timestamp DEFAULT 0; 

impostare il valore predefinito per il creato per colonna a 0. Purtroppo MySQL non consente a due colonne timestamp con valore predefinito CURRENT_TIMESTAMP in una tabella. Per ovviare a ciò è sufficiente inserire un valore NULL nella colonna created e si avranno entrambe le colonne nella data/ora corrente.

INSERT INTO yourTable (col1, created) VALUES ('whatever', NULL); 

O si imposta il valore di default per un timestamp valida come

ALTER TABLE yourTable MODIFY COLUMN created timestamp DEFAULT '1970-01-01 00:00:00'; 

e modificare il trigger in questo modo:

ALTER TRIGGER [dbo].[tr_category_inserted] ON [dbo].[Category] 
AFTER INSERT 
AS 
BEGIN 
    UPDATE Category 
    SET Created = GETDATE() 
/* FROM inserted */ /*don't know where you got that from, do you port from SQL Server?*/ 
    WHERE Category.ID = NEW.ID; 
END 
2

Errore in quanto il trigger funziona solo dopo l'inserimento e non è possibile inserire i valori delle colonne Created e Updated al momento dell'inserimento.

Quindi per eliminare l'errore, è possibile inserire/popolare le colonne Created e Updated insieme a inserire. O È possibile aggiungere la proprietà del valore predefinito della colonna. Si prega di controllare i link per i dettagli

Add column, with default value, to existing table in SQL Server

Specify Default Values for Columns

1

Possibile utilizzo INSTEAD OF grilletto

CREATE TRIGGER [dbo].[tr_category_inserted] ON [dbo].[Category] 
INSTEAD OF INSERT 
AS 
BEGIN 
    INSERT Category(Name, ShowInMenu, Deleted, Created, Updated) 
    SELECT Name, ShowInMenu, Deleted, GETDATE(), GETDATE() 
    FROM inserted i 
END 
0

I tipicamente tutti l'ultima colonna aggiornata deve essere nullo poiché voglio sapere se non è mai stata modificata. Se è necessario mantenere entrambi i campi annullabile vorrei aggiungere un valore predefinito per queste colonne come questo:

ALTER TABLE [dbo].[Category] ADD DEFAULT (getdate()) FOR [Created] 
GO 

ALTER TABLE [dbo].[Category] ADD DEFAULT (getdate()) FOR [LastUpdated] 
GO 

quindi non sarà necessario l'innesco per l'inserto.

Se si desidera utilizzare un trigger in ogni caso, è necessario specificare INSTEAD OF anziché AFTER e includere l'istruzione di inserimento.