我有一个使用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
思想?
答案 0 :(得分:0)
代替自动生成的主键代码应该使用guuid。我认为您的应用程序在多线程模式下运行,多线程之间存在争用条件导致此问题。
答案 1 :(得分:0)
学习发布有用信息。为什么要切断触发器名称,表和类型的实际声明?您还切断了触发器代码的最后一部分。接下来,发布所有错误的完整文本 - 而不是您的解释。最后,阅读所有关于触发器和没有经验的人试图编写它们的问题。
你的问题?在插入和删除块中,您尝试返回结果集 - 不要。你没有错误地复制/粘贴?当你将@action定义为单个字符串时,你打算做什么?你没有真正将它用作变量,那么为什么在使用文字时添加为其分配多字符串的复杂性呢?
最后,您发布的错误消息听起来像是由您的应用程序生成的。最可能的解释是应用程序“看到”触发器的结果集并错误解释信息。
最后一条评论 - 当merge语句导致触发器执行时会发生什么?它会正常工作并记录适当的信息吗?小心你的假设和测试方式。