Я пытался обдумать это, но не могу заставить его работать, поэтому я представляю здесь небольшой тестовый пример, и, надеюсь, кто-нибудь сможет мне его объяснить:
Сначала небольшая тестовая база данных:
CREATE DATABASE test;
USE test;
CREATE TABLE testA (nr INT)
GO
CREATE TRIGGER triggerTestA
ON testA
FOR INSERT AS BEGIN
SET NOCOUNT ON;
IF EXISTS (SELECT nr FROM Inserted WHERE nr > 10)
RAISERROR('Too high number!', 16, 1);
END;
А вот тест tSQL для проверки поведения:
ALTER PROCEDURE [mytests].[test1] AS
BEGIN
EXEC tSQLt.FakeTable @TableName = N'testA'
EXEC tSQLt.ApplyTrigger
@TableName = N'testA',
@TriggerName ='triggerTestA'
EXEC tSQLt.ExpectException
INSERT INTO dbo.testA VALUES (12)
END;
Этот тест будет работать нормально, но триггер не делает то, что я хочу: запретить пользователю вводить значения> 10. Эта версия триггера делает то, что я хочу:
CREATE TRIGGER triggerTestA
ON testA FOR INSERT AS BEGIN
SET NOCOUNT ON;
BEGIN TRANSACTION;
BEGIN TRY
IF EXISTS (SELECT nr FROM Inserted WHERE nr > 10)
RAISERROR('Too high number!', 16, 1);
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
THROW;
END CATCH;
END;
Но теперь тест терпит неудачу, утверждая, что A) есть ошибка (что и ожидалось!) и B) что нет BEGIN TRANSACTION, чтобы соответствовать ROLLBACK TRANSACTION. Я предполагаю, что эта последняя ошибка связана с транзакцией, окружающей tSQLt, и что мой триггер каким-то образом мешает этому, но это определенно не то, что я ожидаю.
Может ли кто-нибудь объяснить, и, может быть, помочь мне сделать это правильно?