|
|
|
непонятное поведение триггера
|
|||
|---|---|---|---|
|
#18+
Извините за длинный пост, так получилось :( Итак, фрагмент кода триггера на insert таблицы TABLE2 (в угловых скобках номер строки): ... <12>/* <13> * PREVENT NULL VALUES IN 'FIELD1' <14> */ <15>IF (SELECT Count(*) FROM inserted WHERE FIELD1 IS NULL) > 0 <16> BEGIN <17> RAISERROR 44444 'Field ''FIELD1'' cannot contain a null value.' <18> ROLLBACK TRANSACTION <19> END <20>/* <21> * PREVENT INSERTS IF NO MATCHING KEY IN 'TABLE1' <22> */ <23>IF (SELECT COUNT(*) FROM inserted) != <24> (SELECT COUNT(*) FROM TABLE1, inserted WHERE (TABLE1.FIELD2 = inserted.FIELD2)) <25> BEGIN <26> RAISERROR(779025, 16, 1) <27> ROLLBACK TRANSACTION <28> END ... вот фрагмент кода процедуры: ... BEGIN BEGIN TRANSACTION INSERT INTO DBO.TABLE1 (FIELD1) VALUES (123) INSERT INTO DBO.TABLE2 (FIELD1, FIELD2) VALUES (123, @PARAM1) COMMIT TRANSACTION SELECT @RETURN_CODE = FIELD2 FROM DBO.TABLE1 WHERE FIELD1 = 123 IF @RETURN_CODE IS NULL -- ошибка вставки SET @RETURN_CODE = -6 END ... вот код, вызываемый в QA: DECLARE @C INT EXEC .SP_MY_PROCEDURE @C OUTPUT, NULL -- @PARAM1 = NULL, т.е. попытка вставить NULL в not nullable-поле SELECT @C GO вот что возвращается после выполнения кода: Server: Msg 3903, Level 16, State 1, Procedure TABLE2_ITrig, Line 27 The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION. Server: Msg 44444, Level 16, State 1, Procedure TABLE2_ITrig, Line 17 Field 'FIELD1' cannot contain a null value. Server: Msg 779025, Level 16, State 1, Procedure TABLE2_ITrig, Line 26 Cannot add or change record. Referential integrity rules require a related record in table ''TABLE1''. The statement has been terminated. т.е. происходит следующее: в процедуре выполняется 2-й insert в транзакции (1-й проходит успешно, как и задумано), срабатывает триггер, проверка (строки 12-19) не проходит, рейзится ошибка (строка 17), происходит роллбэк до начала транзакции в процедуре. Триггер продолжает выполняться, рейзится 2-я ошибка (строка 26), т.к. 1-й роллбэк откатил данные 1-го инсерта, затем попытка выполнить роллбэк уже несуществующей транзакции (строка 27). Таким образом, все стройно и логично :) Но... Во-первых, смущает порядок рейзания ошибок - сначала на 27-й, потом на 17-й и в конце на 26-й строке. Во-вторых, почему 2 первых ошибки не приводят к завершению триггера, а только 3-я (уровень грубости у всех одинаковый)? В-третьих, триггер завершает работу процедуры, чего хотелось бы избежать... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2002, 19:09:14 |
|
||
|
непонятное поведение триггера
|
|||
|---|---|---|---|
|
#18+
Привет! Сдается мне, что сначала вывелась системная ошибка, а потом пользовательские в порядке поступления (см. номера ошибок). Перед откатом можно (нужно?) проверять наличие транзакции :-)) (@@TranCount). Удачи ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2002, 19:35:34 |
|
||
|
непонятное поведение триггера
|
|||
|---|---|---|---|
|
#18+
If a ROLLBACK TRANSACTION is issued in a trigger: 1. All data modifications made to that point in the current transaction are rolled back, including any made by the trigger. 2. The trigger continues executing any remaining statements after the ROLLBACK statement. If any of these statements modify data, the modifications are not rolled back. No nested triggers are fired by the execution of these remaining statements. 3. The statements in the batch after the statement that fired the trigger are not executed. So if the trigger continues executing after the RAISERROR 44444 ROLLBACK TRANSACTION (see p.2) and executes IF (SELECT COUNT(*) FROM inserted) != <24> (SELECT COUNT(*) FROM TABLE1, inserted WHERE (TABLE1.FIELD2 = inserted.FIELD2)) which generate True because there are no already inserted data in TABLE1 (see p.1) and you receive RAISERROR(779025, 16, 1). A then you try rollback transaction one more time but there is no active transaction and server generates error message 3903. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2002, 22:18:45 |
|
||
|
|

start [/forum/topic.php?fid=46&fpage=3365&tid=1818331]: |
0ms |
get settings: |
8ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
29ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
45ms |
get tp. blocked users: |
1ms |
| others: | 210ms |
| total: | 324ms |

| 0 / 0 |
