Sybase ASE для курсора обновления, который дает сбой

Я только что столкнулся со странным поведением ASE (версия 15.7 ESD 15.2) с использованием курсора обновления.
Наконец-то я нашел основную причину, но решил опубликовать ее здесь, потому что она может быть полезна, и, возможно, кто-то уже сталкивался с этим.

Я написал этот простой курсор «для обновления»:

DECLARE c_contactrule 
CURSOR FOR
SELECT a.id
FROM FTContactRule a, Client b, ClientContact c
WHERE /* join conditions */
AND a.client_id IN ( bla bla bla )
AND a.message_subtype_id ( bla bla bla )
AND /* and so on */
for update of a.preferred_medium_id
go

(я немного обобщил запрос для этого поста, чтобы его было удобнее читать)

Далее, конечно, я читаю значение курсора до конца.

open c_contactrule
fetch c_contactrule into @rule_to_update
while @@sqlstatus = 0
begin
     /* do something */
end
close c_contactrule
deallocate c_contactrule
go

Я думаю, вы догадались, что где-то есть update preferred_medium_id where current of

В настоящее время этот запрос дает сбой очень специфическим образом: выдается сообщение «ASE завершил этот процесс», и действительно, он убил мою сессию!

Проведя расследование, я обнаружил, что плохой строкой кода была первая инструкция fetch into.


person nico    schedule 01.06.2016    source источник


Ответы (2)


Если ASE завершает сеанс, вам не повезло столкнуться с ошибкой в ​​ASE. Единственное средство — перейти на более позднюю версию, содержащую исправление. Обратитесь в службу технической поддержки, чтобы узнать, можно ли определить ошибку (в журнале ошибок должна быть трассировка стека) и доступно ли исправление.

Возможно, что если вы перепишете свой запрос по-другому, например, в результате чего будет другой план запроса, ошибка не будет обнаружена, но это не гарантия (и не очень утешительное решение).

person RobV    schedule 02.06.2016

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

Во всяком случае, мои тесты показывают, что проблема связана с тем, что я обновляю поле, которого нет в операторе выбора курсора:

select a.id
....
for update of a.preferred_medium_id

Я просто добавил поле в список выбора и, конечно, добавил переменную в выборку, и все заработало нормально.

select a.id, a.preferred_medium_id
....
for update of a.preferred_medium_id

Однако несколько странно хранить значение в переменной, когда вам не нужно ничего с ней делать.

Кроме того, завершение сеанса не является хорошим ответом сервера. Если для этого существует синтаксическое правило, у нас должна быть ошибка синтаксического анализа, говорящая: «Вы не можете обновить поле, которого нет в списке выбора для курсора обновления».

person nico    schedule 01.06.2016