首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >删除语句上的重复键行插入错误

删除语句上的重复键行插入错误
EN

Stack Overflow用户
提问于 2019-04-23 17:25:47
回答 2查看 83关注 0票数 0

我在SQL中执行以下DELETE语句,但得到以下错误消息。

代码语言:javascript
复制
DELETE PSRO
FROM ROLEUSER PSRO
INNER JOIN PS_GH_AD_X_WALK B ON B.OPRID = PSRO.ROLEUSER
INNER JOIN HSDEV185.HSDEV92B.dbo.PS_JOB C ON C.EMPLID = B.GH_AD_EMPLID AND B.GH_AD_EMPLID <> ''
WHERE C.EFFDT = 
(SELECT MAX(A_ED.EFFDT) FROM HSDEV185.HSDEV92B.dbo.PS_JOB A_ED 
WHERE C.EMPLID = A_ED.EMPLID 
AND A_ED.EFFDT <= SUBSTRING(CONVERT(CHAR,GETDATE(),121), 1, 10)) 


Msg 2601, Level 14, State 1, Procedure ROLEUSER_TR, Line 67
Cannot insert duplicate key row in object 'dbo.AUDIT_ROLEUSR' with unique index 'AUDIT_ROLEUSR'. The duplicate key value is (Native SQL                    , Apr 23 2019  1:15PM, D).
The statement has been terminated.

我不明白为什么SQL将我的DELETE命令解释为插入?

编辑:有以下与ROLEUSER表关联的触发器。我对触发器不太熟悉。在此删除通过SQL执行时,是否有一种方法可以防止插入发生(与系统中的删除在线发生相反,这正是触发器的目的)?

代码语言:javascript
复制
ALTER TRIGGER [dbo].[PSROLEUSER_TR] ON [dbo].[ROLEUSER]
FOR INSERT, UPDATE, DELETE
AS
SET NOCOUNT ON
DECLARE @XTYPE CHAR(1), @OPRID CHAR(30)
SET @OPRID = NULL
SELECT @OPRID = case (charindex(',',
cast(context_info as char(128))))
when 0 then 'Native SQL'
else 
substring(cast(context_info as
CHAR(128)),1,(charindex(',',cast(context_info as char(128)))-1))
end
FROM sys.sysprocesses
WHERE spid = @@spid
-- Determine Transaction Type
IF EXISTS (SELECT * FROM DELETED)
BEGIN
SET @XTYPE = 'D'
END

IF EXISTS (SELECT * FROM INSERTED)
BEGIN
IF (@XTYPE = 'D')
 BEGIN
  SET @XTYPE = 'U'
 END
ELSE
 BEGIN
  SET @XTYPE = 'I'
 END
END
-- Transaction is a Delete
IF (@XTYPE = 'D')
BEGIN
INSERT INTO PS_AUDIT_PSROLEUSR
(AUDIT_OPRID,AUDIT_STAMP,AUDIT_ACTN,
ROLEUSER,
ROLENAME,
DYNAMIC_SW)
SELECT @OPRID,getdate(),'D',
ROLEUSER,
ROLENAME,
DYNAMIC_SW FROM deleted 
END
-- Transaction is a Insert
IF (@XTYPE = 'I')
BEGIN
INSERT INTO PS_AUDIT_PSROLEUSR
(AUDIT_OPRID,AUDIT_STAMP,AUDIT_ACTN,
ROLEUSER,
ROLENAME,
DYNAMIC_SW)
SELECT @OPRID,getdate(),'A',
ROLEUSER,
ROLENAME,
DYNAMIC_SW FROM inserted 
END
-- Transaction is a Update
IF (@XTYPE = 'U')
BEGIN
-- Before Update
INSERT INTO PS_AUDIT_PSROLEUSR
(AUDIT_OPRID,AUDIT_STAMP,AUDIT_ACTN,
ROLEUSER,
ROLENAME,
DYNAMIC_SW)
SELECT @OPRID,getdate(),'K',
ROLEUSER,
ROLENAME,
DYNAMIC_SW FROM deleted 
-- After Update
INSERT INTO PS_AUDIT_PSROLEUSR
(AUDIT_OPRID,AUDIT_STAMP,AUDIT_ACTN,
ROLEUSER,
ROLENAME,
DYNAMIC_SW)
SELECT @OPRID,getdate(),'N',
ROLEUSER,
ROLENAME,
DYNAMIC_SW FROM inserted 
END
EN

回答 2

Stack Overflow用户

发布于 2019-04-23 17:40:30

使用类似的东西

代码语言:javascript
复制
alter index AUDIT_ROLEUSR on TableName
    rebuild with (ignore_dup_key = on)

或者检查第67行的过程ROLEUSER_TR,确保没有触发器。

编辑:

如果希望定期执行此删除,则可以创建一个过程,该过程将禁用索引、执行删除并将其打开。

票数 0
EN

Stack Overflow用户

发布于 2019-04-23 17:41:47

是否有一种方法可以防止在通过SQL执行此删除时发生插入(与系统中的删除在线发生相反)

不是直接的,不是。但在某些情况下,可以对触发器进行编码,使其不采取任何行动。例如,如果将此添加到触发器的开头:

代码语言:javascript
复制
if user_id() = 1 return;

当DBO (数据库所有者或sysadmin)运行命令时,它将立即退出,但会为其他任何人运行触发器体。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55816478

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档