Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 主键冲突,即使记录不存在_Sql_Sql Server_Triggers_Sql Server 2012 - Fatal编程技术网

Sql 主键冲突,即使记录不存在

Sql 主键冲突,即使记录不存在,sql,sql-server,triggers,sql-server-2012,Sql,Sql Server,Triggers,Sql Server 2012,我正在使用SQL Server 2012 我已经创建了一个触发器,代码如下 但我有点困惑,因为在我的表上运行更新查询时,我会收到一条错误消息“违反主键约束”。但是,在我查询表的地方,我正在更新的值在表中不存在?目录是主键列 update myTable set directory = 'madeup2' where directory = 'madeup' 因此,上面的查询是导致违反主键约束的原因 但是我执行下面的select查询,在我的表中没有名为madeup2的目录-没有返回任何记录 se

我正在使用SQL Server 2012

我已经创建了一个触发器,代码如下

但我有点困惑,因为在我的表上运行更新查询时,我会收到一条错误消息“违反主键约束”。但是,在我查询表的地方,我正在更新的值在表中不存在?目录是主键列

update myTable
set directory = 'madeup2'
where directory = 'madeup'
因此,上面的查询是导致违反主键约束的原因

但是我执行下面的select查询,在我的表中没有名为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
更新

感谢那些指出我的触发器中的update语句缺少where子句的评论

但有一件事我不明白,我用where子句执行了一个更新查询。但是在插入的表中,我只会有新的“directory”值,那么如何创建where子句呢


这仅仅是使用已删除表的情况吗?因此,请从mytable中删除该表中的记录,然后将插入表中的记录添加到mytable?

在触发器中,您的第一次更新没有WHERE子句。第二个有一个WHERE子句,它不引用正在更新的表

这意味着它将尝试使用插入表中的相同值更新表中的每一行


此外,您的触发器未编码为处理影响多行的插入/更新。

此update语句没有where子句。它将尝试更新表中每个记录的目录字段。每当表中有多条记录时,这将导致主键冲突

        update mytable
        set directory = inserted.directory,
        pathNumber = inserted.pathNumber,
        userName = inserted.userName
        from inserted;
UPDATE语句将更新整个表,而不仅仅是那些已修改的行。这通常不是你想要的

您需要在插入的伪表和要更新的实际基础数据表之间添加联接

 if @permission = 1
 begin
     update mytable
     set directory = inserted.directory,
         pathNumber = inserted.pathNumber,
         userName = inserted.userName
     from inserted i
     inner join mytable on i.ID = mytable.ID;  -- or whatever column is your PK
    end

UPDATE语句将更新整个表,而不仅仅是那些已修改的行。这通常不是您想要的-您需要在插入的伪表和要更新的实际底层数据表之间添加一个连接。哦,当然!您的权利谢谢-我不想更新整个表。如果您将您的评论作为答案,我会更正如何调整触发器,使其能够处理受影响的多行?将插入的表连接到相应列上的mytable表。由于目录是您的PK,您可能应该加入其中。但我真的不清楚为什么你希望触发器处理插入、更新和删除,而代码只执行更新。我删除了处理插入和删除的代码,以使我的示例更易于阅读