-1

在 SQL Server 2008 R2 中,我希望创建一个模仿 OracleBEFORE INSERT触发器行为的触发器,其中任何插入的触发器都会在持久化之前将 UPDATE_TS 和 CREATE_TS 更新为当前时间戳。

我现在看到的问题是错误:只能在使用列列表并且 IDENTITY_INSERT 为 ON 时指定表“MY_TABLE”中标识列的显式值

我不确定在触发器中打开 SET IDENTITY INSERT 表然后关闭 SET IDENTITY INSERT 表是否是个好主意。也许这是一个可能的解决方案。

请就最佳实践提出建议。

示例表称为 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
4

2 回答 2

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

于 2013-11-11T21:09:14.457 回答
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 触发器类似,但不完全相同。

于 2013-11-15T15:27:16.470 回答