Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Хр. процедура удаления приводит к работе триггера -> Не ловится ошибка.
|
|||
|---|---|---|---|
|
#18+
Извините, если вопрос не совсем по теме. Ситуация такая: Родитель a - потомки b,c,d...(это таблицы). База построена на CONSTRAINT-ах PK, FK. (MSSQL 7.0) Процедура удаления родителя(a) проверяет наличие ссылок в таблицах потомков b, c , d ... , и удаляет потомков перед удалением родителя и в конце процедуры удаляет запись из таблицы a . (транзакция в хр. процедуре) Для таблицы родитель(a) существует триггер на удаление, он проверяет использование идентификаторов удаляемых родителей в текстовых строках, хранящихся в отдельной таблице.(Это формулы, в них могут в текстовом виде храниться иментификаторы переменных.) Триггер откатывает операцию, если переменная(родитель) используется в какой-либо формуле. Проблема в следующем: При вызове хр. процедуры удаления из Visual Basic(ADO 2.6) объект Connection получает ошибку в Errors, но при этом не возникает Runtime-ошибки исполнения программы. Однако если выполнить удаление из таблицы (а) через тот-же объект Command, но с помощью команды "DELETE a WHERE ...", то возникает Runtime-ошибка, и ловится обработчиком. Ошибка та-же самая, созданная в триггере. Я могу конечно перенести всю логику из хр. процедуры в триггер и отказаться от процедуры, но однако из-за чего такое может происходить? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2002, 17:22 |
|
||
|
Хр. процедура удаления приводит к работе триггера -> Не ловится ошибка.
|
|||
|---|---|---|---|
|
#18+
Ну во первых интересно, что пишет QA ? Возникает ли в нем ошибка при вызове ХП ? Во вторых в тригере при откате неплохо бы писать RAISERROR с текстом ошибки для клиента. В третьих в ХП поставить после DELETE строку IF @@ERROR <> 0 RETURN (ну или код обработки ошибки). Кстати на заметку - если желательно автоматом прерывать ХП при возникновении ошибок системного уровня, генерируемого сервером (нарушение целостной ссылочности, ошибки constraint и т.д.), то в начале ХП можно поставить SET XACT_ABORT ON. Однако для генерирующихся юзерных ошибок оператором RAISERROR это не поможет, так что по любому лучше после критических выполнений операций над БД (INSERT, UPDATE, DELETE) писать обработку кода ошибки, иначе процедура просто продолжит свое выполнение и многое чего натворит, если повезет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2002, 19:14 |
|
||
|
Хр. процедура удаления приводит к работе триггера -> Не ловится ошибка.
|
|||
|---|---|---|---|
|
#18+
1. В QA все выглядит правильно - прерывается выполнение процедуры по ошибке, которую создает триггер. 2. В триггере я пишу: ... --если найдена формула, использующая переменную RAISERROR ('Удаление переменной не возможно. Переменная используется в расчетных формулах.', 16, 10) ROLLBACK TRAN RETURN ... 3. В процедуре удаления: CREATE PROCEDURE DelVar @cVarName varchar(33) AS ... BEGIN TRANSACTION ... DELETE FROM cfVariable WHERE cVarName = @cVarName -- это центральная таблица переменных(родитель) IF @@ERROR <> 0 BEGIN ROLLBACK TRANSACTION return(-1) END COMMIT return(0) GO При таком вызове: cmd.CommandText = "DELETE FROM cfVariable WHERE cVarName = '" & strVarName & "'" cmd.CommandType = adCmdText cmd.Execute возникает Runtime-ошибка и ошибка находится в коллеции cmd.ActiveConnection.Errors. Однако, когда вызываю из VB cmd.CommandType = adCmdStoredProc cmd.CommandText = "DelVar" cmd.Parameters.Refresh cmd.Parameters("@cVarName") = strVarName cmd.Execute ,то возвращаемое значение из процедуры(cmd.Parameters.Item(0)) = 0, хотя должно быть -1, и Runtime-ошибки не происходит. Но при этом ошибка находится в коллекции cmd.ActiveConnection.Errors. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2002, 07:45 |
|
||
|
Хр. процедура удаления приводит к работе триггера -> Не ловится ошибка.
|
|||
|---|---|---|---|
|
#18+
Написал, отдельный скрипт, демонситирующий мой вопрос. Каждый может попробовать вызвать хр. процедуру удаления через ADODB.Command (своей среды разработки клиентов) и убедиться, что Runtime-ошибка не возникнет и возвращаемое значение из хр. процедуры будет = 0. Однако в коллекции cmd.ActiveConnection.Errors ошибка будет находиться. 1. Это так и должно работать, или я что-то делаю неправильно ? 2. Почему возвращаемое значение из хр. процедуры не -1 ? use pubs --DROP TABLE cfVariable CREATE TABLE cfVariable( VarID int NOT NULL IDENTITY(1,1), cVarName varchar(33) NOT NULL, UNIQUE(cVarName), PRIMARY KEY(VarID)) --DROP TABLE cfCalcRule CREATE TABLE cfCalcRule( ID int NOT NULL IDENTITY (1,1), left_id int NOT NULL, left_field varchar(20) NULL, right_val varchar(255), PRIMARY KEY (ID), FOREIGN KEY (left_id) REFERENCES cfVariable (VarID) ) GO --DROP TRIGGER tD_cfVariable CREATE TRIGGER tD_cfVariable ON cfVariable FOR DELETE AS IF @@ROWCOUNT = 0 RETURN -- переменные для хранения записи из курсора DECLARE @VarID int DECLARE @cVarName varchar(33) DECLARE VDBVars CURSOR LOCAL FAST_FORWARD READ_ONLY FOR SELECT cVarName FROM deleted OPEN VDBVars FETCH NEXT FROM VDBVars INTO @cVarName -- получаем первую запись из курсора WHILE @@FETCH_STATUS = 0 BEGIN IF EXISTS(SELECT 1 FROM cfCalcRule WHERE PATINDEX('%' + @cVarName + '%',cfCalcRule.right_val) <> 0) BEGIN RAISERROR ('Удаление переменной невозможно. Переменная используется в расчетных формулах.', 16, 10) ROLLBACK TRAN RETURN END FETCH NEXT FROM VDBVars INTO @cVarName -- переход к следующей запси END CLOSE VDBVars DEALLOCATE VDBVars GO CREATE PROCEDURE DelVar @cVarName varchar(33) AS DECLARE @VarID int --Проверка входного параметра IF (@cVarName IS NULL) BEGIN RETURN(-1) END --Определяем идентификатор переменной SELECT @VarID=VarID FROM cfVariable WHERE cVarName = @cVarName IF @@ROWCOUNT = 0 --Нет такой переменной в cfVariable BEGIN RETURN(-1) END BEGIN TRANSACTION DELETE cfCalcRule WHERE left_id = @VarID -- Удаление переменой из центральной таблицы DELETE FROM cfVariable WHERE cVarName = @cVarName IF @@ERROR <> 0 -- Я так понимаю, что это не отрабатывает. BEGIN ROLLBACK TRANSACTION return(-1) END COMMIT return(0) GO -------------------------------------------- ПРООВЕРКА ----------------------------------------------------------- -- Заполнение данными --SELECT * FROM cfVariable INSERT INTO cfVariable (cVarName) VALUES ('testVar1') GO INSERT INTO cfVariable (cVarName) VALUES ('testVar2') GO -- Добавление формулы в таблицу расчетных переменных -- <имя переменной>.<имя поля> = <формула> -- SELECT * FROM cfCalcRule DECLARE @VarID int SELECT @VarID = VarID FROM cfVariable WHERE cVarName = 'testVar1' INSERT INTO cfCalcRule (left_id , left_field, right_val) VALUES (@VarID, 'val', 'testVar2 + 1000 / testVar2') GO -- Проверка удаления из cfVariable DELETE cfVariable WHERE cVarName = 'testVar2' GO -- Проверка удаления с помощью хр. процедуры DECLARE @RETURN_VALUE int EXEC @RETURN_VALUE = DelVar @cVarName = 'testVar2' PRINT '@RETURN_VALUE = ' + CONVERT(varchar(10),@RETURN_VALUE) GO ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2002, 09:28 |
|
||
|
Хр. процедура удаления приводит к работе триггера -> Не ловится ошибка.
|
|||
|---|---|---|---|
|
#18+
Только-что проверил. Ошибка генерится в обоих случаях. Я думаю, тут тонкости подключения - какой провайдер? Или, может, поставить SET NOCOUNT ON в скрипты создания и в коннекте... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2002, 13:34 |
|
||
|
Хр. процедура удаления приводит к работе триггера -> Не ловится ошибка.
|
|||
|---|---|---|---|
|
#18+
Лучше бы поменять местами в триггере RAISERROR и ROLLBACK - а то получается, что процедура ловит переменную @@ERROR, которая после ROLLBACK будет показывать 0 - так как эта команда нормально отрабатывается. Почему ошибка в VB не показывается, не знаю, так как не спец. Но как вариант могу предложить, если и при перестановке операторов не будет срабатывать, то в ХП в условие обработки ошибки еще раз вгонять RAISERROR - как говорится, не хочет по хорошему ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2002, 16:07 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=32028986&tid=1822902]: |
0ms |
get settings: |
6ms |
get forum list: |
20ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
37ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
38ms |
get tp. blocked users: |
1ms |
| others: | 267ms |
| total: | 385ms |

| 0 / 0 |
