插入非空列后触发

时间:2013-01-24 08:51:29

标签: sql sql-server tsql triggers

我的表格包含两个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插入“Created”列表中   '类别';列不允许空值。 INSERT失败。

插入命令:

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

如何在没有设置这些列的情况下编写此类触发器以允许null?

4 个答案:

答案 0 :(得分:3)

像这样修改你的表:

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

将created to列的默认值设置为0.遗憾的是,MySQL不允许在一个表中使用默认CURRENT_TIMESTAMP的两个时间戳列。要解决此问题,您只需在NULL列中插入created值,您就会有两列到当前时间戳。

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 :(得分:2)

发生错误,因为触发器仅在插入后工作,并且您可能无法在插入时插入列值CreatedUpdated

因此,为了消除错误,您可以插入/填充列CreatedUpdated以及插入。 要么 您可以添加列的默认值属性。请查看链接了解详情

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

Specify Default Values for Columns

答案 2 :(得分: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

答案 3 :(得分:0)

我通常允许最后更新的列为null,因为我想知道它是否从未被更改过。如果你必须保持两个字段都可以为空,我会在这些列中添加一个默认值,如下所示:

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

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

然后你不需要插入的触发器。

如果你真的想要使用触发器,你必须指定INSTEAD OF而不是AFTER并包含插入语句。