#sql #sql-server
#sql #sql-сервер
Вопрос:
У меня есть следующие 3 таблицы, и я пытаюсь изменить схему, чтобы учесть уникальность для [Проверки].FromCompanyID, [Проверить].ToCompanyID и [ActivityToCheck].ActivityId. Кроме добавления двух FromCompanyID и ToCompanyID в таблицу [ActivityToCheck], как я мог бы внести изменения в схему, чтобы добавить ограничение уникальности в одну из таблиц?
CREATE TABLE [dbo].[Activity](
[ActivityID] [int] IDENTITY(1,1) NOT NULL,
[UserID] [int] NOT NULL,
[StartDate] [date] NOT NULL,
[EndDate] [date] NOT NULL,
[Description] [nvarchar](255) NULL
--<OTHER COLUMNS>
)
CREATE TABLE [dbo].[Check](
[CheckID] [int] IDENTITY(1,1) NOT NULL,
[CheckNumber] [nvarchar](255) NOT NULL,
[CheckDate] [date] NOT NULL,
[CheckDescription] [nvarchar](255) NULL,
[FromCompanyID] [int] NOT NULL,
[ToCompanyID] [int] NOT NULL
--<OTHER COLUMNS>
)
CREATE TABLE [dbo].[ActivityToCheck](
[ActivityToCheckID] [int] IDENTITY(1,1) NOT NULL,
[ActivityID] [int] NOT NULL,
[CheckID] [int] NOT NULL
)
РЕДАКТИРОВАТЬ: будет ли представление, привязанное к схеме, разумным способом обеспечения уникальности:
CREATE VIEW TestView
WITH SCHEMABINDING AS
SELECT ActivityToCheckID, CheckNumber, CheckID, FromCompanyID, ToCompanyID, ActivityID, AmountPaid
FROM [dbo].[Check] c
inner join [dbo].ActivityToCheck a on c.CheckID = a.CheckID
GO
CREATE UNIQUE CLUSTERED INDEX testindex on TestView (FromCompanyID, ToCompanyID, ActivityID)
GO
Спасибо,
Комментарии:
1. Если я правильно понимаю, вы хотите, чтобы
ActivityToCheck
быть уникальным дляCheckID
каждого, это правильно?2. Извините, проверка ActivityToCheck должна быть уникальной для FromCompanyID, ToCompanyID и ActivityId, по сути, чего я пытаюсь избежать, так это того, что два человека из FromCompany добавляют один и тот же ActivityId к нескольким разным проверкам, отправляемым в ToCompany.
Ответ №1:
Вы должны использовать следующий триггер для dbo.Check
таблицы :
CREATE TRIGGER YourTriggerName ON dbo.[check]
INSTEAD OF INSERT
AS BEGIN
IF EXISTS(SELECT *
FROM Inserted i
INNER JOIN dbo.ActivityToCheck a1 ON i.CheckId = a1.CheckId
INNER JOIN dbo.ActivityToCheck a2 ON a2.ActivityId = a1.ActivityId
INNER JOIN dbo.[CHECK] c ON c.CheckId = a2.CheckId AND c.FromCompanyId=i.FromCompanyId AND c.ToCompanyId=i.ToCompanyId) BEGIN
RAISERROR('Your information is duplicate.',16,1)
RETURN;
End
INSERT INTO dbo.[check] (CheckNumber, CheckDate, CheckDescription, FROMCompanyId, ToCompanyId)
SELECT CheckNumber, CheckDate, CheckDescription, FROMCompanyId, ToCompanyId
FROM Inserted
END
также вы должны создать вместо триггера обновления для dbo.Check
таблицы, если FromCompanyId или ToCompanyId редактируемый и может быть изменен.
Комментарии:
1. Эти таблицы потенциально могут стать очень большими, я бы хотел воздержаться от выполнения нескольких соединений каждый раз, когда я вставляю запись.
2. Эффект запуска при вставке записи в таблицу и связанный с объемом транзакции вставки в вашей таблице. и не связано с объемом записи в таблице.