У меня есть два 2008 таблицы SQL Server: расписания (родителя) и ScheduleResults (ребенок)Невозможно создать Вместо Trigger
CREATE TABLE Schedules(
ID int identity primary key NOT NULL,
Status nvarchar(3)
) [ON PRIMARY]
и
CREATE TABLE ScheduleResults(
ID int identity primary key NOT NULL,
ScheduleID int NOT NULL CONSTRAINT [FK_ScheduleResults_Schedules] REFERENCES Schedules(ID) ON DELETE CASCADE,
IsEndOfRun bit NOT NULL CONSTRAINT DF_ScheduleResults_IsEndOfRun DEFAULT(0)
) [ON PRIMARY]
Логика в том, что после того, как вставить/обновить/удалить ребенка, я смотрю на всех детей для родителя. Если какой-либо из них имеет IsEndOfRun = 1, то статус записи родительских расписаний переходит в «DEA», иначе он переходит в «ACT». Если ни один не найден, он по-прежнему переходит к «ACT».
Так вот мой триггер:
CREATE TRIGGER ScheduleResultsStatus
ON [ScheduleResults] AFTER INSERT, UPDATE, DELETE
AS
SET NOCOUNT ON;
DECLARE @ScheduleID int
DECLARE @IsEORSum int
SELECT @ScheduleID=ScheduleID FROM inserted
SELECT @IsEORSum=COUNT(*) FROM ScheduleResults WHERE [email protected] AND IsEndOfRun=1
IF @IsEORSum=0
BEGIN
-- There are no EndOfRun results. Schedule should be active
UPDATE Schedules SET Status='ACT' WHERE [email protected]
END
ELSE
BEGIN
-- There is at least 1 record with IsEndOfRun=True. Schedule should be DEACTIVATED
UPDATE Schedules SET Status='DEA' WHERE [email protected]
END
После вставки отлично работает. После обновления работает отлично. После удаления не работает. С этим сообщением появляется предупреждение:
Невозможно создать INSTEAD OF DELETE TRIGGER. Это связано с тем, что таблица имеет внешний ключ с каскадным удалением.
Мое первоначальное определение действительно имело предложение ВКЛЮЧИТЬ УДАЛЕНИЕ КАСКАДА в столбце ScheduleID. Я удалил его, но не успел. Кроме того, как вы видите, я создаю триггер AFTER, а не триггер INSTEAD. Итак, теперь мой вопрос ... Как настроить Trigger и/или FK Constraint, чтобы я мог позаботиться о ссылочной целостности и позаботиться о сценариях удаления детей?
Я ценю любую помощь от всех мастеров SQL Server.
Примечание стороны: видя это заявление 'Select @ ScheduleID = ScheduleID FROM inserted', кажется, что вы думаете, что триггер будет вызываться один раз для каждой строки - это ** не ** дело; триггер будет вызываться ** один раз за оператор **, и если этот оператор влияет на несколько строк, псевдо-таблица «Inserted» будет содержать ** несколько строк **. Вы должны написать свой код запуска таким образом, чтобы он мог обрабатывать несколько строк в 'Inserted' - ваш код в настоящее время не может этого сделать. –
Вам действительно нужно ** хранить ** этот статус? - похоже, было бы просто вычислить его во время извлечения (вы могли бы создать представление, содержащее логику, если хотите) –
А также в дополнение к комментарию marc_s - не 'COUNT()', когда все вы хотите сделать, это установить существование или нет. 'EXISTS()' существует по какой-либо причине. –