Ниже таблица Country
:
+------------------+-----------+
| COLUMN_NAME | DATA_TYPE |
+------------------+-----------+
| ID | int |
| Name | varchar |
| CapitalCity | varchar |
| Population | int |
| OfficialReligion | varchar |
| OfficialLanguage | varchar |
| DateEntered | datetime |
+------------------+-----------+
У меня есть еще одна очень похожая таблица с именем CountryRecord
, в которой есть те же столбцы, а затем еще две новые:
+-------------------------+-----------+
| COLUMN_NAME | DATA_TYPE |
+-------------------------+-----------+
| ID | int |
| OriginalID | int |
| Name | varchar |
| CapitalCity | varchar |
| Population | int |
| OfficialReligion | varchar |
| OfficialLanguage | varchar |
| DateEntered | datetime |
| QueryType | varchar |
+-------------------------+-----------+
При вставке, обновлении или удалении данных в Country
вызывается триггер, который также вставляет строки в CountryRecord
с целью записи того, какой запрос был сделан для какой строки данных. Триггер выглядит следующим образом:
ALTER TRIGGER [dbo].[CountryRecord_Trigger]
ON [dbo].[Country]
AFTER UPDATE, INSERT, DELETE
AS
DECLARE @CountryID INT, @queryType VARCHAR(20);
--Update trigger
IF EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted)
BEGIN
SET @queryType = 'UPDATE';
SELECT @CountryID = ID FROM inserted i;
INSERT INTO CountryRecord (OriginalID, Name, CapitalCity, Population, OfficialReligion, OfficialLanguage, DateEntered, QueryType)
SELECT
ID, Name, CapitalCity, Population, OfficialReligion,
OfficialLanguage, DateEntered, @queryType
FROM
Country
WHERE
@CountryID = ID;
END
--Insert trigger
IF EXISTS (SELECT * FROM inserted) AND NOT EXISTS (SELECT * FROM deleted)
BEGIN
SET @queryType = 'INSERT';
SELECT @CountryID = ID FROM inserted i;
INSERT INTO CountryRecord (OriginalID, Name, CapitalCity, Population, OfficialReligion, OfficialLanguage, DateEntered, QueryType)
SELECT
ID, Name, CapitalCity, Population, OfficialReligion,
OfficialLanguage, DateEntered, @queryType
FROM
Country
WHERE
@CountryID = ID;
END
--Delete trigger
IF NOT EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted)
BEGIN
SET @queryType = 'DELETE';
SELECT @CountryID = ID FROM deleted d;
INSERT INTO CountryRecord (OriginalID, Name, CapitalCity, Population, OfficialReligion, OfficialLanguage, DateEntered, QueryType)
SELECT
ID, Name, CapitalCity, Population, OfficialReligion,
OfficialLanguage, DateEntered, @queryType
FROM
Country
WHERE
@CountryID = ID;
END
Однако, хотя триггеры вставки и обновления работают, триггер удаления не работает. Когда я запускаю запрос на удаление, я выбираю только одну строку, поэтому я вполне уверен, что запрос на удаление не выбирает более одной строки (вместо этого, похоже, что он ничего не выбирает, так как делает проверку текущей идентичности CountryRecord
после выполнения запроса на удаление видно, что он не увеличился на единицу).
Обновление: Изменение триггера удаления на использование ELSE
вместо выполнения набора условий не решает проблему. Вместо этого любые запросы на обновление будут вызывать триггер обновления и удаления, в то время как запросы на удаление по-прежнему не действуют.
Обновление 2: Просто чтобы убедиться, что я воздействовал только на одну строку, я добавил в запросы на выборку для каждого триггера, а также вывод @CountryID
- запросы на выборку показали только 1 строку, в то время как @CountryID
не отображается как ноль / пусто. Я также пытался изменить столбцы, думая, что ограничение NOT NULL оказало какое-либо влияние, но это не так.
Обновление 3: У меня теперь работает Delete, хотя он работает только для удаления одной строки. Многострочные удаления не работают должным образом - если, например, я удаляю две записи, в таблицу аудита попадает только одна строка. Я также обновил «Вставить и обновить», чтобы использовать аналогичную структуру кода, чтобы они также имели одну и ту же проблему с несколькими строками. Фрагмент кода для удаляемой части:
SET @queryType = 'DELETE';
SELECT CountryID = ID FROM deleted;
INSERT INTO CountryRecord (OriginalID, Name, CapitalCity, Population, OfficialReligion, OfficialLanguage, DateEntered, QueryType)
SELECT ID, Name, CapitalCity, Population, OfficialReligion, OfficialLanguage, DateEntered, @queryType FROM deleted WHERE @CountryID = ID;
DECLARE @auditID int;
SET @auditID = SCOPE_IDENTITY();
UPDATE CountryRecord SET QueryType = @queryType WHERE ID = @auditID;