数据库生成了一个已被使用的密钥,由Trigger引起?

时间:2018-02-01 04:18:26

标签: sql-server triggers

我有一个使用LINQ to SQL的传统制作软件,它有自己的数据库。我想在该数据库中的一个表上创建一个触发器,并让它执行一些连接,并使另一个数据库中的字段保持其值。现在发生的是触发器我在遗留应用程序中遇到此错误: “数据库生成了一个已经在使用的密钥。”

如果我移除触发器,则按照惯例进行操作。

这是触发器:

BEGIN
SET NOCOUNT ON;

DECLARE @action as char(1);

if exists(SELECT * from inserted) and exists (SELECT * from deleted)
    begin
        SET @action = 'UPDATE';
        INSERT INTO ste.dbo.Logs([LogEvent],[RaisedBy],[LogTime])
        SELECT
            itemID,
            'ListLineItem (' + ListLineItemID + '): ' + @action,
            GETDATE()
        FROM INSERTED
    end
If exists (Select * from inserted) and not exists(Select * from deleted)
    begin
        SET @action = 'INSERT';
        update soli
            set soli.itemRefNumber = wo.RefNum,
                soli.itemIssueDate = wo.IssueDate
        from ste.dbo.ListLineItems soli
        join INSERTED woli on soli.ListLineTxnID = woli.ListLineItemID
        join cse.dbo.item wo on woli.itemID = wo.IDKey

        SELECT
            itemID,
            'ListLineItem (' + ListLineItemID + '): ' + @action,
            GETDATE()
        FROM INSERTED
    end
If exists(select * from deleted) and not exists(Select * from inserted)
    begin 
        SET @action = 'DELETE';
        update soli
            set soli.itemRefNumber = null,
                soli.itemIssueDate = '19000101'
        from ste.dbo.ListLineItems soli
        join deleted woli on soli.ListLineTxnID = woli.ListLineItemID
        join cse.dbo.item wo on woli.itemID = wo.IDKey
        SELECT
            itemID,
            'ListLineItem (' + ListLineItemID + '): ' + @action,
            GETDATE()
        FROM deleted
    end
 END

思想?

2 个答案:

答案 0 :(得分:0)

代替自动生成的主键代码应该使用guuid。我认为您的应用程序在多线程模式下运行,多线程之间存在争用条件导致此问题。

答案 1 :(得分:0)

学习发布有用信息。为什么要切断触发器名称,表和类型的实际声明?您还切断了触发器代码的最后一部分。接下来,发布所有错误的完整文本 - 而不是您的解释。最后,阅读所有关于触发器和没有经验的人试图编写它们的问题。

你的问题?在插入和删除块中,您尝试返回结果集 - 不要。你没有错误地复制/粘贴?当你将@action定义为单个字符串时,你打算做什么?你没有真正将它用作变量,那么为什么在使用文字时添加为其分配多字符串的复杂性呢?

最后,您发布的错误消息听起来像是由您的应用程序生成的。最可能的解释是应用程序“看到”触发器的结果集并错误解释信息。

最后一条评论 - 当merge语句导致触发器执行时会发生什么?它会正常工作并记录适当的信息吗?小心你的假设和测试方式。