以下觸發器是在三個相關表之一上定義的,它會更新另一個表。但它不起作用。相反,它會拋出: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
動作,插入到臨時表沒有約束等
任何想法?
該功能讓我哭了。它在做什麼?多語句表值函數通常比標量函數更慢。 –
Id是標識列。速度不在這裏。我使用這張表來生成一堆使用普通查詢的代碼片段。片段由GUID分隔。由於C#支持在Azure SQL數據庫中暫時掛起,因此我使用T-SQL的PATINDEX作爲正則表達式替換來提取GUID。 – CalvinDale
你有其他觸發器嗎?你是否確定100%是這個觸發器中的INSERT行是這個問題?我建議你在你的觸發器中刪除'ORDER BY' - 它沒有做任何事情。 –