2017-04-06 19 views
0

以下觸發器是在三個相關表之一上定義的,它會更新另一個表。但它不起作用。相反,它會拋出:T-SQL觸發器拋出:更新或刪除的行值不會使行唯一或它們改變多行

第3行中的數據未提交。 錯誤源:Microsoft.SqlServer.Management.DataTools。 錯誤消息:更新或刪除的行值不會使行唯一,或者它們會更改多行(24行)。

CREATE TABLE [Develop].[TemplateSqlProjects] 
(
    [Id] INT IDENTITY (1, 1) NOT NULL, 
    [Name] NVARCHAR (50) NOT NULL, 
    CONSTRAINT [PK_Develop.TemplateSqlProjects] PRIMARY KEY CLUSTERED ([Id] ASC) 
); 
GO 

CREATE UNIQUE NONCLUSTERED INDEX [Develop_TemplateSqlProjects_Name_Unique] 
    ON [Develop].[TemplateSqlProjects]([Name] ASC); 
GO 
------------------------------------------------------------------------------------------------- 
CREATE TABLE [Develop].[TemplateSqlStatements] 
(
    [Id] INT IDENTITY (1, 1) NOT NULL, 
    [ProjectId] INT NOT NULL, 
    [SqlStatement] NVARCHAR (MAX) NOT NULL, 
    CONSTRAINT [PK_Develop.TemplateSqlStatements] PRIMARY KEY NONCLUSTERED ([Id] ASC), 
    CONSTRAINT [FK_Develop.TemplateSqlStatements_Develop.TemplateSqlProjects_ProjectId] 
     FOREIGN KEY ([ProjectId]) REFERENCES [Develop].[TemplateSqlProjects] ([Id]) ON DELETE CASCADE 
); 
------------------------------------------------------------------------------------------------- 
CREATE TABLE [Develop].[TemplateSqlStatementGuids] 
(
    [Id] INT IDENTITY (1, 1) NOT NULL, 
    [SqlStatementId] INT NOT NULL, 
    [Guid] UNIQUEIDENTIFIER NOT NULL, 
    CONSTRAINT [PK_Develop.TemplateSqlStatementGuids] PRIMARY KEY NONCLUSTERED ([Id] ASC), 
    CONSTRAINT [FK_Develop.TemplateSqlStatementGuids_Develop.TemplateSqlStatements_SqlStatementId] 
     FOREIGN KEY ([SqlStatementId]) REFERENCES [Develop].[TemplateSqlStatements] ([Id]) ON DELETE CASCADE 
); 

GO 
CREATE UNIQUE CLUSTERED INDEX [SqlStatementId_Guid_Unique] 
    ON [Develop].[TemplateSqlStatementGuids]([SqlStatementId] ASC, [Guid] ASC); 
GO 
CREATE NONCLUSTERED INDEX [Develop_TemplateSqlStatementGuids_Guid] 
    ON [Develop].[TemplateSqlStatementGuids]([Guid] ASC); 
GO 
------------------------------------------------------------------------------------------------- 
CREATE TRIGGER [Develop].[Trigger_Develop_TemplateSqlStatements_AfterInsertOrUpdate] ON [Develop].[TemplateSqlStatements] 
AFTER INSERT, UPDATE, DELETE 
AS 
BEGIN 

    DELETE FROM Develop.TemplateSqlStatementGuids 
    WHERE SqlStatementId IN (SELECT Id FROM DELETED); 

    DELETE FROM Develop.TemplateSqlStatementGuids 
    WHERE SqlStatementId IN (SELECT Id FROM INSERTED); 

    INSERT INTO Develop.TemplateSqlStatementGuids (SqlStatementId, [Guid]) 
    SELECT DISTINCT i.Id, f.Value 
    FROM INSERTED i 
    CROSS APPLY Utility.ft_ExtractGuids(i.SqlStatement) f 
    ORDER BY i.Id, f.Value 

END 
GO 
------------------------------------------------------------------------------------------------- 
CREATE FUNCTION [Utility].[ft_ExtractGuids] (@Text NVARCHAR(MAX)) 
RETURNS @Guids TABLE (Value UNIQUEIDENTIFIER) 
AS 
BEGIN 
    DECLARE @IndexStart AS BIGINT; 
    DECLARE @IndexEnd AS BIGINT; 
    SELECT @IndexStart = PATINDEX(N'%' + REPLACE(N'00000000-0000-0000-0000-000000000000', N'0', N'[0-9a-fA-F]') + N'%', @Text) 
    WHILE @IndexStart > 0 AND LEN(@Text) > 36 
     BEGIN 
      INSERT INTO @Guids (Value) VALUES (TRY_CONVERT(UNIQUEIDENTIFIER, SUBSTRING(@Text, @IndexStart, 36))); 
      SET @Text = SUBSTRING(@Text, @IndexStart + 36, LEN(@Text) - 36); 
      SET @IndexStart = PATINDEX(N'%' + REPLACE(N'00000000-0000-0000-0000-000000000000', N'0', N'[0-9a-fA-F]') + N'%', @Text); 
     END 
    DELETE FROM @Guids WHERE Value = N'00000000-0000-0000-0000-000000000000'; 
    RETURN; 
END 

它似乎應該工作。這些值是唯一的。我已經嘗試了許多變化,如消除, DELETE動作,插入到臨時表沒有約束等

任何想法?

+1

該功能讓我哭了。它在做什麼?多語句表值函數通常比標量函數更慢。 –

+0

Id是標識列。速度不在這裏。我使用這張表來生成一堆使用普通查詢的代碼片段。片段由GUID分隔。由於C#支持在Azure SQL數據庫中暫時掛起,因此我使用T-SQL的PATINDEX作爲正則表達式替換來提取GUID。 – CalvinDale

+0

你有其他觸發器嗎?你是否確定100%是這個觸發器中的INSERT行是這個問題?我建議你在你的觸發器中刪除'ORDER BY' - 它沒有做任何事情。 –

回答

0

請檢查下面的選擇,你試圖插入到TemplateSqlStatementGuids表。

SELECT DISTINCT i.Id, f.Value 
    FROM INSERTED i 
    CROSS APPLY Utility.ft_ExtractGuids(i.SqlStatement) f 
    ORDER BY i.Id, f.Value 

看來你試圖插入f.value到GUID列使用交叉應用。如我錯了請糾正我。

+0

每個f.Value是一個GUID。 – CalvinDale