簡體   English   中英

即使記錄不存在也違反主鍵

[英]primary key violation even though record doesn't exist

我正在使用SQL Server 2012。

我創建了一個觸發器,代碼如下。

我有點困惑,盡管在表上運行更新查詢時會收到錯誤消息“違反PRIMARY KEY約束”。 但是,在查詢表的地方,要更新的值在表中不存在? 目錄是主鍵列。

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

更新

感謝指出我觸發器中的update語句缺少where子句的注釋。

我不明白的一件事是我執行了帶where子句的更新查詢。 雖然在插入的表中,我將僅具有新的“目錄”值,所以如何創建where子句?

這僅僅是使用已刪除表的一種情況-因此從mytable中刪除該表中的記錄,然后將插入表中的記錄添加到mytable中嗎?

您的UPDATE語句將更新整個表-不僅是那些已被修改的行。 通常這不是您想要的。

您需要在Inserted偽表和要更新的實際基礎數據表之間添加一個JOIN

 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沒有WHERE子句。 第二個有一個WHERE子句,它不引用要更新的表。

這意味着它將嘗試使用插入表中的相同值來更新表中的每一行。

同樣,您的觸發器未編碼為處理影響多行的插入/更新。

此更新語句沒有where子句。 它將嘗試更新表中每個記錄的directory字段。 每當表中有多個記錄時,這都會導致主鍵沖突。

        update mytable
        set directory = inserted.directory,
        pathNumber = inserted.pathNumber,
        userName = inserted.userName
        from inserted;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM