"select..into" внутри хранимой процедуры Firebird - PullRequest
2 голосов
/ 25 июля 2011

Я использую Firebird 2.5 64bit edition. У меня есть две таблицы Master (A) и Detail (B), и я установил каскадное обновление и удаление для B, поэтому, если я удаляю запись в мастере, любые связанные записи в детали также удаляются

Я установил После удаления триггер для таблицы B, которая выполняет и передает параметры в хранимую процедуру

Эта хранимая процедура имеет следующий SQL:

  select STATUS from A
  where A.PK_id = :PK_id
  INTO :var_status;

Проблема в том, что я всегда получаю NULL для переменной var_status, хотя я проверил ее в редакторе SQL и получаю 1, что является правильным значением, я также проверил (используя отладчик IBexpert) переданный параметр :PK_id и это тоже правильно!

Почему я получаю неправильное значение, хранящееся в этой переменной.

1 Ответ

4 голосов
/ 26 июля 2011

Вероятная проблема в том, что вы используете AFTER DELETE, а записи больше нет. Вот порядок действий:

  • Запись удаляется из A
  • Удаление из каскадов A до удаления на B
  • Триггер AFTER DELETE в B. вызывается.
  • Из триггера вы пытаетесь получить доступ к данным не из B, а из A. Его больше нет.

Помните, что триггер работает внутри транзакции. Поэтому, вероятно, когда вы запускаете тот же SELECT, вы можете получить доступ к значению, потому что вы находитесь в другой транзакции, а исходная транзакция еще не была зафиксирована.

Это не так тривиально на самом деле. Вот несколько вариантов решения вашей проблемы:

  • Проверьте, можно ли изменить ваши бизнес-правила, чтобы вы могли запускать эту часть кода не в триггере в B, а в A, где статус будет доступен. В конце концов, вам нужно что-то делать из-за А, а не Б.
  • В конечном итоге вы можете удалить cascade delete и обработать удаление B из триггера AFTER DELETE в A. Таким образом, все будет в одном блоке кода.
...