2008-12-11 140 views
1

我有一个名为ApprovalTask​​s表...认证有一个状态栏很奇怪的SQL更新问题

我也有一个名为ApprovalsView

当我尝试了直更新视图:

update ApprovalTasks set Status = 2 where ApprovalTaskID = 48 

我收到此错误消息:

Msg 2601, Level 14, State 1, Line 1 
Cannot insert duplicate key row in object 'dbo.ApprovalsView' with unique index 'IX_ApprovalTaskID'. 
The statement has been terminated. 

任何想法为什么会发生这种情况?

下面是创建表的脚本:

USE [CSPMOSSApplication] 
GO 
/****** Object: Table [dbo].[ApprovalTasks] Script Date: 12/11/2008 12:41:35 ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[ApprovalTasks](
    [ApprovalTaskID] [int] IDENTITY(1,1) NOT NULL, 
    [ApproverID] [int] NOT NULL, 
    [DueDate] [datetime] NULL, 
    [Status] [smallint] NOT NULL, 
    [ApprovedRejectedDate] [datetime] NULL, 
    [Reason] [nvarchar](1024) COLLATE Finnish_Swedish_CI_AS NULL, 
    [OrganizationID] [int] NOT NULL, 
    [TicketID] [int] NOT NULL, 
    [Link] [nchar](255) COLLATE Finnish_Swedish_CI_AS NULL, 
    [GlobalApproverID] [int] NULL, 
CONSTRAINT [PK_Approval_Tasks] PRIMARY KEY CLUSTERED 
(
    [ApprovalTaskID] ASC 
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY] 
) ON [PRIMARY] 

GO 
USE [CSPMOSSApplication] 
GO 
ALTER TABLE [dbo].[ApprovalTasks] WITH NOCHECK ADD CONSTRAINT [FK_Approval_Tasks_ApprovalTaskStatuses] FOREIGN KEY([Status]) 
REFERENCES [dbo].[ApprovalTaskStatuses] ([ApprovalTaskStatusID]) 
GO 
ALTER TABLE [dbo].[ApprovalTasks] CHECK CONSTRAINT [FK_Approval_Tasks_ApprovalTaskStatuses] 
GO 
ALTER TABLE [dbo].[ApprovalTasks] WITH NOCHECK ADD CONSTRAINT [FK_Approval_Tasks_Organizations] FOREIGN KEY([OrganizationID]) 
REFERENCES [dbo].[Organizations] ([OrganizationID]) 
GO 
ALTER TABLE [dbo].[ApprovalTasks] CHECK CONSTRAINT [FK_Approval_Tasks_Organizations] 
GO 
ALTER TABLE [dbo].[ApprovalTasks] WITH NOCHECK ADD CONSTRAINT [FK_Approval_Tasks_Tickets] FOREIGN KEY([TicketID]) 
REFERENCES [dbo].[Tickets] ([TicketID]) 
GO 
ALTER TABLE [dbo].[ApprovalTasks] CHECK CONSTRAINT [FK_Approval_Tasks_Tickets] 
GO 
ALTER TABLE [dbo].[ApprovalTasks] WITH NOCHECK ADD CONSTRAINT [FK_Approval_Tasks_Users] FOREIGN KEY([ApproverID]) 
REFERENCES [dbo].[Users] ([UserID]) 
GO 
ALTER TABLE [dbo].[ApprovalTasks] CHECK CONSTRAINT [FK_Approval_Tasks_Users] 

PK_Approval_Tasks(集群)

USE [CSPMOSSApplication] 
GO 
/****** Object: Index [PK_Approval_Tasks] Script Date: 12/11/2008 12:45:50 ******/ 
ALTER TABLE [dbo].[ApprovalTasks] ADD CONSTRAINT [PK_Approval_Tasks] PRIMARY KEY CLUSTERED 
(
    [ApprovalTaskID] ASC 
)WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY] 

IX_ApprovalTask​​ID(Clsutered)

SE [CSPMOSSApplication] 
GO 
SET ARITHABORT ON 
GO 
SET CONCAT_NULL_YIELDS_NULL ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
SET ANSI_NULLS ON 
GO 
SET ANSI_PADDING ON 
GO 
SET ANSI_WARNINGS ON 
GO 
SET NUMERIC_ROUNDABORT OFF 
GO 
/****** Object: Index [IX_ApprovalTaskID] Script Date: 12/11/2008 12:47:27 ******/ 
CREATE UNIQUE CLUSTERED INDEX [IX_ApprovalTaskID] ON [dbo].[ApprovalsView] 
(
    [ApprovalTaskID] ASC 
)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY] 

创建视图脚本

USE [CSPMOSSApplication] 
GO 
-- ============================================= 
-- Script Template 
-- ============================================= 

-- [ApprovalTasks]: add columns Link, GlobalApproverID 
IF NOT EXISTS(SELECT 1 FROM sysobjects,syscolumns WHERE sysobjects.id = syscolumns.id 
AND sysobjects.name = 'ApprovalTasks' AND syscolumns.name = 'Link') 
BEGIN 
    ALTER TABLE ApprovalTasks ADD [Link] [nchar] (255) COLLATE Finnish_Swedish_CI_AS NULL 
    PRINT 'Column ApprovalTasks.Link was added.' 
END 
IF NOT EXISTS(SELECT 1 FROM sysobjects,syscolumns WHERE sysobjects.id = syscolumns.id 
AND sysobjects.name = 'ApprovalTasks' AND syscolumns.name = 'GlobalApproverID') 
BEGIN 
    ALTER TABLE ApprovalTasks ADD [GlobalApproverID] [int] NULL 
    PRINT 'Column ApprovalTasks.GlobalApproverID was added.' 

    ALTER TABLE [dbo].[ApprovalTasks] WITH NOCHECK ADD CONSTRAINT [FK_Approval_Tasks_GlobalApproverID] FOREIGN KEY([GlobalApproverID]) 
    REFERENCES [dbo].[Users] ([UserID]) 

    ALTER TABLE [dbo].[ApprovalTasks] CHECK CONSTRAINT [FK_Approval_Tasks_GlobalApproverID] 
END 

-- [ApprovalsView] 
IF EXISTS (SELECT * FROM sys.fulltext_indexes fti WHERE fti.object_id = OBJECT_ID(N'[dbo].[ApprovalsView]')) 
BEGIN 
    DROP FULLTEXT INDEX ON [dbo].[ApprovalsView] 
    PRINT 'FULLTEXT INDEX on [ApprovalsView] was dropped.' 
END 
GO 

IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[ApprovalsView]') AND name = N'IX_ApprovalTaskID') 
BEGIN 
    DROP INDEX IX_ApprovalTaskID ON [dbo].[ApprovalsView] WITH (ONLINE = OFF) 
    PRINT 'INDEX IX_ApprovalTaskID was dropped.' 
END 
GO 

IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[ApprovalsView]')) 
DROP VIEW [dbo].[ApprovalsView] 

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

CREATE VIEW [dbo].[ApprovalsView] 
WITH SCHEMABINDING 
AS 
SELECT  at.ApprovalTaskID, 
      at.ApproverID, 
      at.DueDate, 
      at.Status, 
      ats.ApprovalTaskStatusTranslationKey AS StatusText, 
      at.ApprovedRejectedDate, 
      at.Reason, 
      at.OrganizationID, 
      ord.Name AS OrderName, 
      ord.TotalPrice, 
      ord.SubmitDate, 
      ord.OrdererID, 
      usr.FirstName AS OrdererFirstName, 
      usr.LastName AS OrdererLastName, 
      ordi.Items_Name AS ItemName, 
      ordi.Items_Description AS ItemDescription, 
      ordi.OtherInformation AS ItemInformation, 
      oir.RecipientFullName, 
      CONVERT(nvarchar(250), oir.DeliveryAddress) As DeliveryAddress, 
      ti.Description 

FROM  dbo.ApprovalTasks at 
    INNER JOIN 
     dbo.ApprovalTaskStatuses ats ON ats.ApprovalTaskStatusID = at.Status 
    INNER JOIN 
     dbo.Orders_Items_Recipients oir ON oir.TicketID = at.TicketID 
    INNER JOIN 
     dbo.Orders_Items ordi ON ordi.Orders_ItemsID = oir.Orders_ItemsID 
    INNER JOIN 
     dbo.Orders ord ON ordi.OrderID = ord.OrderID 
    INNER JOIN 
     dbo.Users usr ON ord.OrdererID = usr.UserID 
    INNER JOIN 
     dbo.Tickets ti ON ti.TicketID = at.TicketID 
GO 

CREATE UNIQUE CLUSTERED INDEX [IX_ApprovalTaskID] ON [dbo].[ApprovalsView] 
(
    [ApprovalTaskID] ASC 
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY] 
GO 

CREATE FULLTEXT INDEX ON [dbo].[ApprovalsView](
[DeliveryAddress] LANGUAGE [Neutral], 
[ItemDescription] LANGUAGE [Neutral], 
[ItemInformation] LANGUAGE [Neutral], 
[ItemName] LANGUAGE [Neutral], 
[OrdererFirstName] LANGUAGE [Neutral], 
[OrdererLastName] LANGUAGE [Neutral], 
[OrderName] LANGUAGE [Neutral], 
[Reason] LANGUAGE [Neutral], 
[RecipientFullName] LANGUAGE [Neutral]) 
KEY INDEX [IX_ApprovalTaskID] ON [ApprovalSearchCatalog] 
WITH CHANGE_TRACKING AUTO 
GO 

ALTER FULLTEXT CATALOG [ApprovalSearchCatalog] rebuild 

PRINT 'Catalog [ApprovalSearchCatalog] task to rebuild fulltext index was sent.' 


-- STORED PROCEDURES 

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ReceiveApprovalTasksFromQueue]') AND type in (N'P', N'PC')) 
DROP PROCEDURE [dbo].[ReceiveApprovalTasksFromQueue] 
GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
EXEC dbo.sp_executesql @statement = N' 
-- ============================================= 
-- Author:  Petr Klozik 
-- Create date: 19.11.2008 
-- Description: Gets approvals which DueDate is over ReferenceDate (now) 
-- ============================================= 
CREATE Procedure [dbo].[ReceiveApprovalTasksFromQueue] 
    @Limit int 
As 
BEGIN 

    SET NOCOUNT ON; 

    If Not @Limit Is Null Set RowCount @Limit 

    -- Status: WaitingForApproval = 1 
    Select Tasks.ApprovalTaskID 
    From ApprovalTasks Tasks 
    Where Status = 1 And DueDate < GetDate() 

END 
' 
GO 
GRANT EXECUTE ON [dbo].[ReceiveApprovalTasksFromQueue] TO [OMT_IntegrationRole] 
GO 
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[UpdateApprovalTaskInfo]') AND type in (N'P', N'PC')) 
DROP PROCEDURE [dbo].[UpdateApprovalTaskInfo] 
GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
EXEC dbo.sp_executesql @statement = N' 
-- ============================================= 
-- Author:  Klozik Petr 
-- Create date: 2008-11-25 
-- Description: Updates Approval task info to DB 
-- ============================================= 
CREATE PROCEDURE [dbo].[UpdateApprovalTaskInfo] 
    @ApprovalTaskID int, 
    @DueDate datetime, 
    @ApprovalRejectDate datetime, 
    @Reason nvarchar(1024), 
    @Status int, 
    @GlobalApproverID int 
AS 
BEGIN 
    SET NOCOUNT ON; 

    Update ApprovalTasks 
     Set DueDate = @DueDate, 
     ApprovedRejectedDate = @ApprovalRejectDate, 
     Reason = @Reason, 
     Status = @Status, 
     GlobalApproverID = @GlobalApproverID 
     Where ApprovalTaskID = @ApprovalTaskID 
END 

' 
GO 
GRANT EXECUTE ON [dbo].[UpdateApprovalTaskInfo] TO [OMT_IntegrationRole] 
GO 
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[GetUserById]') AND type in (N'P', N'PC')) 
DROP PROCEDURE [dbo].[GetUserById] 
GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
EXEC dbo.sp_executesql @statement = N' 
-- ============================================= 
-- Author:  Klozik Petr 
-- Create date: 2008-12-04 
-- Description: Gets user row by the specified ID. 
-- ============================================= 

CREATE PROCEDURE [dbo].[GetUserById] 
(
    @UserID int 
) 

AS 
BEGIN 
    SELECT 
     UserID, 
     RTRIM(SID) [SID], 
     RTRIM(OMTGUID) [OMTGUID], 
     RTRIM(UserAccount) [UserAccount], 
     RTRIM(Email) [Email], 
     RTRIM(FirstName) [FirstName], 
     RTRIM(LastName) [LastName], 
     RTRIM(Country) [Country], 
     RTRIM(City) [City], 
     RTRIM(PostalNumber) [PostalNumber], 
     RTRIM(StreetAddress) [StreetAddress], 
     RTRIM(PhoneNumber) PhoneNumber, 
     Modified, 
     Deleted, 
     Uploaded, 
     UploadCode, 
     UploadStatus, 
     RTRIM(Users.ADUserAccount) AS ADUserAccount 
    FROM 
     [dbo].[Users] 
    WHERE 
     UserID = @UserID 
END 
' 
GO 
GRANT EXECUTE ON [dbo].[GetUserById] TO [OMT_IntegrationRole] 
GO 
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[GetApprovalTaskInfoById]') AND type in (N'P', N'PC')) 
DROP PROCEDURE [dbo].[GetApprovalTaskInfoById] 
GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
EXEC dbo.sp_executesql @statement = N' 


-- ============================================= 
-- Author:  Petr Klozik 
-- Create date: 19.11.2008 
-- Description: Gets approvals which DueDate is over ReferenceDate (now) 
-- ============================================= 
CREATE Procedure [dbo].[GetApprovalTaskInfoById] 
    @ApprovalTaskID int 
As 
BEGIN 

    SET NOCOUNT ON; 

    Declare @OrganizationID int 
    Declare @CurrentApproverID int 
    Declare @NewApproverID int 
    Declare @NewOrganizationID int 

    Select @OrganizationID = OrganizationID, @CurrentApproverID = ApproverID 
     From ApprovalTasks 
     Where ApprovalTaskID = @ApprovalTaskID 

    Set @NewApproverID = (
      Select Top 1 o.GlobalApproverID 
      From Organizations o 
       Inner Join OrganizationDescendants od On od.OrganizationID = o.OrganizationID 
      Where od.DescendantID = @OrganizationID 
       And Not(o.GlobalApproverID Is Null) 
      Order By o.OrganizationLevel Desc 
     ) 

    If Not(@NewApproverID Is Null) 
    Begin 
     Set @NewOrganizationID = (
      Select OrganizationID 
       from Organizations 
       Where GlobalApproverID = @NewApproverID) 
    End 

    Select Tasks.*, Tickets.Description AS TicketDescription, 
     Tickets.RequestorID, Tickets.OrdererID, 
     @NewApproverID AS OrgGlobalApproverID, 
     @NewOrganizationID AS OrgGlobalApproverOrganizationID 
    From ApprovalTasks Tasks 
    inner join Tickets Tickets on Tasks.TicketID = Tickets.TicketID 
    Where ApprovalTaskID = @ApprovalTaskID 

END 
' 
GO 
GRANT EXECUTE ON [dbo].[GetApprovalTaskInfoById] TO [OMT_IntegrationRole] 
GO 
+0

你能给我们提供ApprovalsView的定义吗? – VVS 2008-12-11 10:53:50

+0

您可以添加视图的定义吗? – RobS 2008-12-11 10:54:09

+0

问题在于视图,所以我们需要视图的定义。 – 2008-12-11 11:14:00

回答

2

看看索引的定义IX_ApprovalTask​​ID 是否有可能存在于ApprovalTask​​ID,StatusID唯一键约束这意味着不存在与状态表= 2 & ApprovalTask​​ID = 48

我同意其他行用户学习,它看起来像有一个有关ApprovalTask​​s UPDATE触发器被插入到ApprovalTask​​ID ApprovalView

尝试运行DISABLE TRIGGER ALL ON ApprovalTasks并重新运行更新

4

幸运的猜测:任何UPDATE触发器定义?

第二个幸运猜测:ApprovalsView是一个indexed view,它在更新ApprovalTask​​表后违反了其索引。

1

它看起来像是一个视图已被创建,它是或者包括您正在更新的表,并且当视图正在被更新时更新时发生错误。

也许该视图包含来自不同表格的数据不兼容或者设置了更严格的约束?

2

由于错误来自对象dbo.ApprovalsView,问题是在ApprovalsTask上尝试更新该表的触发器。我真的认为ApprovalsView是一个表格而不是视图。但是你必须已经检查过了。