I have a SQL Server database with the following tables:
CREATE TABLE [dbo].[Rule]
(
[RuleId] [int] IDENTITY(1,1) NOT NULL,
[Value1] [int] NOT NULL,
[Value2] [int] NOT NULL,
[Value3] [int] NOT NULL,
CONSTRAINT [PK_Rule] PRIMARY KEY CLUSTERED ([RuleId] ASC)
)
GO
CREATE TABLE [dbo].[Type]
(
[TypeId] [INT] IDENTITY(1,1) NOT NULL,
[Description] [varchar](50) NOT NULL,
CONSTRAINT [PK_Type] PRIMARY KEY CLUSTERED ([TypeId] ASC)
)
GO
CREATE TABLE [dbo].[RuleType]
(
[RuleId] [int] NOT NULL,
[TypeId] [int] NOT NULL,
CONSTRAINT [PK_RuleType] PRIMARY KEY CLUSTERED ([RuleId] ASC, [TypeId] ASC)
)
GO
ALTER TABLE [dbo].[RuleType] WITH CHECK ADD CONSTRAINT [FK_RuleType_Type] FOREIGN KEY([TypeId])
REFERENCES [dbo].[Type] ([TypeId])
GO
ALTER TABLE [dbo].[RuleType] CHECK CONSTRAINT [FK_RuleType_Type]
GO
ALTER TABLE [dbo].[RuleType] WITH CHECK ADD CONSTRAINT [FK_RuleType_Rule] FOREIGN KEY([RuleId])
REFERENCES [dbo].[Rule] ([RuleId])
GO
ALTER TABLE [dbo].[RuleType] CHECK CONSTRAINT [FK_RuleType_Rule]
GO
/*Test data*/
INSERT INTO [dbo].[Type] ([Description]) VALUES ('Type1'), ('Type2'), ('Type3');
GO
INSERT INTO [dbo].[Rule] ([Value1], [Value2], [Value3]) VALUES (1,1,1), (2,2,2), (3,3,3);
GO
INSERT INTO [dbo].[RuleType] ([RuleId], [TypeId]) VALUES (1,1), (1,2), (1,3), (2,2), (2,3);
GO
The following stored procedure returns all the rules and an aggregate value of their associated types:
CREATE OR ALTER PROCEDURE SelectRules
AS
SELECT
R.[RuleId],
R.[Value1],
R.[Value2],
R.[Value3],
[AssoctiatedTypes] = STRING_AGG(RT.TypeId, ', ')
FROM
[dbo].[Rule] R
LEFT JOIN
[dbo].[RuleType] RT ON RT.RuleId = R.RuleId
GROUP BY
R.[RuleId],
R.[Value1],
R.[Value2],
R.[Value3]
GO
Question:
Is there a way to enforce uniqueness on the combination Value1, Value2, Value3 and AssociatedTypes?
What I need to prevent is the creation of a new rule with the same values (Value1, Value2 and Value3) and the same associated types as an existing rule. The same enforcement should apply for updating an existing rule.