【发布时间】:2015-11-02 15:01:27
【问题描述】:
我使用的是 SQL Server 2012。
我已经创建了一个触发器,代码如下。
虽然在我的表上运行更新查询时我收到一条错误消息“违反主键约束”,但我有点困惑。但是,在我查询表的地方,我正在更新的值在表中不存在?目录是主键列。
update myTable
set directory = 'madeup2'
where directory = 'madeup'
所以上面的查询是导致违反主键约束的原因。
但我执行下面的选择查询,我的表中没有名为 madeup2 的目录 - 没有返回记录。
select * from myTable where directory = 'madeup2'
这和我的触发器有关吗?
create trigger trDefaultPath on mytable
instead of insert, update, delete
as
begin
declare @defCountIns int
declare @retVal int
declare @permission bit
select @defCountIns = count(userName) from inserted where userName = 'Default'
select @retVal = count(HostName) from UserHostName where HostName = HOST_NAME()
-- workout permissions
if @retVal = 0 and @defCountIns > 0
set @permission = 0
else
set @permission = 1
begin
if @permission = 1
begin
update mytable
set directory = inserted.directory,
pathNumber = inserted.pathNumber,
userName = inserted.userName
from inserted;
end
else
begin
update mytable
set directory = inserted.directory,
pathNumber = inserted.pathNumber,
userName = inserted.userName
from inserted
where inserted.username <> 'Default';
print 'Do not have permission to update directories'
end
end
end
更新
感谢 cmets 指出我的触发器中的更新语句缺少 where 子句。
我不明白的一件事是我使用 where 子句执行了更新查询。在插入的表中,虽然我将只有新的“目录”值,那么如何创建 where 子句?
这仅仅是使用已删除表的情况 - 所以从 mytable 中删除该表中的记录,然后将插入表中的记录添加到 mytable 中?
【问题讨论】:
-
您的
UPDATE语句将更新整个 表——而不仅仅是那些已修改的行。这通常不是您想要的 - 您需要在您的Inserted伪表和您要更新的实际基础数据表之间添加一个JOIN。 -
哦,当然!对了,谢谢-我不想更新整个表格。如果您将评论作为答案,我将使其正确
标签: sql sql-server triggers sql-server-2012