【发布时间】:2019-04-26 12:27:52
【问题描述】:
我正在尝试创建一个“历史”表,每次更新源表中的一行时都会更新该表。
这是我用来创建历史记录表的 (SQL Server) 代码:
DROP TABLE eventGroup_History
SELECT
CAST(NULL AS UNIQUEIDENTIFIER) AS NewId,
CAST(NULL AS varchar(255)) AS DoneBy,
CAST(NULL AS varchar(255)) AS Operation,
CAST(NULL AS datetime) AS DoneAt,
*
INTO
eventGroup_History
FROM
eventGroup
WHERE
1 = 0
GO
ALTER TABLE eventGroup_History
ALTER COLUMN NewId UNIQUEIDENTIFIER NOT NULL
go
ALTER TABLE eventGroup_History
ADD PRIMARY KEY (NewId)
GO
ALTER TABLE eventGroup_History
ADD CONSTRAINT DF_eventGroup_History_NewId DEFAULT NewSequentialId() FOR NewId
GO
触发器是这样创建的:
drop trigger eventGroup_LogUpdate
go
create trigger eventGroup_LogUpdate
on dbo.eventGroup
for update
as
declare @Now as DateTime = GetDate()
set nocount on
insert into eventGroup_History
select @Now, SUser_SName(), 'update-deleted', *
from deleted
insert into eventGroup_History
select SUser_SName(), 'update-inserted', @Now, *
from inserted
go
exec sp_settriggerorder @triggername = 'eventGroup_LogUpdate', @order = 'last', @stmttype = 'update'
但是当我在 SQL Server Management Studio 中更新一行时,我收到一条消息:
第 2 行中的数据未提交。
错误来源:.Net SqlClient 数据提供程序。
错误信息:从字符串转换为唯一标识符时转换失败。
我认为触发器正在尝试将 SUserSName() 作为行的第一列插入,但那是 PK NewId:
表中没有其他唯一标识符列。
如果我从 SQL Management Studio 的编辑网格中添加行,则无需指定 NewId 值即可添加行。
那么,为什么 SQL Server 触发器会尝试使用INSERT INTO 子句中的第一项填充NewId,而不是跳过它以让正常的IDENTITY 操作提供值?
(以及如何阻止这种情况发生以使触发器起作用?)
【问题讨论】:
标签: sql sql-server triggers uniqueidentifier database-trigger