2013-01-24 27 views
11

我有一张表,其中包含两个not nullCreatedUpdated在非空列上插入后触发

我写了相应的触发

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 

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 

,但如果我插入新行我得到一个错误

无法将NULL值插入列“创建',表 'Category';列不允许有空值。 INSERT失败。

Insert命令:

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

我怎么能写这样的触发器没有设置这些列允许空?

+8

如果您想在'insert'上自动更新'date',我建议您使用'default'约束来代替'triggers' – DON

+3

发生错误是因为触发器仅在插入后工作,您可能不会插入列值插入时创建'和'更新'。 – TechDo

+1

由于触发器的名称已经说过,触发器会触发** AFTER **插入发生 - 但是您需要为任何NOT NULL列在INSERT上提供**值**。所以你需要编写一个'INSTEAD OF INSERT'触发器来设置这些列的初始值 - 或者更容易:只需在该列上定义一个'DEFAULT(GETDATE())'约束,这样它就会自动填充到'INSERT '...... –

回答

3

修改你的表是这样的:

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

为已创建的列0默认不幸的是MySQL的不允许两个时间戳列,默认为CURRENT_TIMESTAMP。为了解决这个问题,你只需要在created列中插入一个NULL的值,并且你将有两列到当前的时间戳。

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

或者你设置默认为有效的时间戳像

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

,并修改触发这样的:

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 
1

可能使用INSTEAD OF触发

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

我通常都是由于我想知道它是否从未被更改过,所以最后更新的列是空的。如果你必须保持两个字段为空的我将默认值添加到这样的那些列:

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

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

然后,你将不再需要用于插入扳机。

如果您确实想要使用触发器,您将不得不指定INSTEAD OF而不是AFTER并包含insert语句。