在SQL Server 2008 R2中,我希望创建一个模仿Oracle BEFORE INSERT
触发器行为的触发器,其中任何插入的触发器都会将UPDATE_TS和CREATE_TS更新为当前时间戳坚持不懈。
发布我现在看到的是错误: 只有在使用列列表且IDENTITY_INSERT为ON时,才能指定表'MY_TABLE'中标识列的显式值
我不确定将SET IDENTITY INSERT表打开然后再打开是否是个好主意 触发器中的SET IDENTITY INSERT表OFF。也许这是一个可能的解决方案。
请告知最佳做法。
示例表名为MY_TABLE:
CREATE TABLE [myschema].[MY_TABLE](
[MY_TABLE_ID] [bigint] IDENTITY(1,1) NOT NULL,
[FIELD_TO_UPDATE] [varchar](255) NOT NULL,
[CREATE_TS] [datetime] NULL,
[UPDATE_TS] [datetime] NULL),
PRIMARY KEY (MY_TABLE_ID))
触发:
CREATE TRIGGER my_table_create_ts_trigger
ON [mydb].myschema.MY_TABLE
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO MY_TABLE([MY_TABLE_ID], [FIELD_TO_UPDATE], [CREATE_TS], [UPDATE_TS])
SELECT i.MY_TABLE_ID, i.FIELD_TO_UPDATE, GETDATE(), GETDATE()
FROM INSERTED as i
END
答案 0 :(得分:6)
不确定为什么使用动态SQL,并不是真的需要它。此外,之后无需执行UPDATE
,您可以这样做:
CREATE TRIGGER my_table_create_ts_trigger
ON [mydb].myschema.MY_TABLE
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO MY_TABLE(<list of every non identity column here>)
SELECT <list of every non identity column and the date here>, GETDATE()
FROM INSERTED
END
此外,您应该在INSERT
和SELECT
中明确列出列。
答案 1 :(得分:3)
我必须是一个贪婪的惩罚,但我有一个更好的建议。 放下触发器。
将您的表格更改为:
CREATE TABLE [myschema].[MY_TABLE](
[MY_TABLE_ID] [bigint] IDENTITY(1,1) NOT NULL,
[FIELD_TO_UPDATE] [varchar](255) NOT NULL,
-- change this column to have a default:
[CREATE_TS] [datetime] NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- and this column too, I guess:
[UPDATE_TS] [datetime] NOT NULL DEFAULT CURRENT_TIMESTAMP),
PRIMARY KEY (MY_TABLE_ID))
为什么要允许这些列为NULL?为什么要使用复杂的触发器来替换使用默认约束更简单的实现?
您不需要触发器,我不明白它带来了什么好处或者您想要复制BEFORE触发器的原因。 INSTEAD OF触发器类似,但不完全相同。