13

我有一个包含两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 插入到列“已创建”、表“类别”中;列不允许空值。插入失败。

插入命令:

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

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

4

4 回答 4

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在一个表中有两个带默认值的时间戳列。要克服这个问题,您只需在列中插入一个NULLcreated,您将拥有当前时间戳的两列。

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
于 2013-01-24T09:27:14.660 回答
2

Created发生错误是因为触发器仅在插入后起作用,并且您可能没有在插入Updated时插入列值。

因此,为了消除错误,您可以插入/填充列Created以及Updated插入。或者您可以添加列的默认值属性。请检查链接以获取详细信息

将具有默认值的列添加到 SQL Server 中的现有表

指定列的默认值

于 2013-01-24T09:16:51.607 回答
2

可能使用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
于 2013-01-24T09:54:46.160 回答
0

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

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

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

那么您将不需要插入的触发器。

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

于 2013-12-18T16:44:19.677 回答