下面的触发器在三个相关表中的一个上定义,并更新另一个表。然而,它不起作用。相反,它抛出:
第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
操作,插入没有约束的 temp 表等等。
有什么想法吗?
答案 0 :(得分: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列中。如果我错了,请纠正我。