24.12.2008, 18:26 | #1 |
MCITP
|
Eщё приколы про курсоры
Простой пример (проект из 3.0 во вложении):
Таблица ZVVTestTable, на ней одно поле ID, на ней же метод update X++: public void update() { super(); info("Update " + this.ID); } X++: static void ZVVTestJob(Args _args) { ZVVTestTable ZVVTestTable; int i; ; ttsBegin; delete_from ZVVTestTable; for (i=1; i<=5; i++) { ZVVTestTable.clear(); ZVVTestTable.ID = int2str(i); ZVVTestTable.insert(); } info("First Update:"); update_recordset ZVVTestTable setting ID = ZVVTestTable.ID; info("Second Update:"); select ZVVTestTable where ZVVTestTable.ID == "НЕТУ ТАКОГО"; update_recordset ZVVTestTable setting ID = ZVVTestTable.ID; info("Third Update:"); select firstOnly ZVVTestTable where ZVVTestTable.ID == "НЕТУ ТАКОГО"; update_recordset ZVVTestTable setting ID = ZVVTestTable.ID; ttsCommit; } Цитата:
Сообщение (17:13:38)
First Update: Update 1 Update 2 Update 3 Update 4 Update 5 Second Update: Update 1 Update 2 Update 3 Update 4 Update 5 Third Update: Update 1 Склонен считать это багом... UPD: PS Кстати, попробовал на 4-ке то же самое - уже такого эффекта нет, обновляет все строчки в последнем случае тоже. Значит всё-таки был баг и исправили. На 3-ке - будьте бдительны.
__________________
Zhirenkov Vitaly Последний раз редактировалось ZVV; 24.12.2008 в 18:37. |
|
|
За это сообщение автора поблагодарили: sukhanchik (2). |
24.12.2008, 18:39 | #2 |
Administrator
|
я бы не стал считать это багом. Это вполне ожидаемый баг разработчика повторного использования одних и тех же переменных. Курсор в select и курсор в update должны отличаться. И если первый был выбран с определенными параметрами - то как система должна догадаться, что в update_recordset она должна выполнить операцию без оглядки на первый курсор?
Т.е. рекомендация такая. Есть переменные, которые используются для выборки (только чтения). Есть переменные, которые используются для записи (выбранные с forupdate). И есть переменные, которые по сути своей курсора в БД не создают (ну с т.з. разработчика это не видно), а лишь обозначают таблицу, над которой надо выполнить определенные действия (это для delete_from и update_recordset). Ведь выбрав записи без forupdate никто ж не пытается обновить данные. А если хочется обновить - то делается повторная выборка с forupdate. Так и тут - эта переменная просто обозначает таблицу и не должна нести на себе "груз" дополнительной ответственности. Так что это больше похоже на фичу. Но весьма интересную фичу. - Я тебе дал два яблока. Затем потом одно забрал. Сколько у тебя осталось? - Одно - Неправильно. Ведь неизвестно - сколько их было у тебя до того как я тебе их дал.
__________________
Возможно сделать все. Вопрос времени |
|
|
За это сообщение автора поблагодарили: Gustav (2). |
24.12.2008, 18:50 | #3 |
MCITP
|
Цитата:
В случае явного курсора такого бы не произошло. И обратите внимание на отредактированное исходное сообщение... Цитата:
UPD:
PS Кстати, попробовал на 4-ке то же самое - уже такого эффекта нет, обновляет все строчки в последнем случае тоже. Значит всё-таки был баг и исправили. На 3-ке - будьте бдительны.
__________________
Zhirenkov Vitaly |
|
24.12.2008, 19:01 | #4 |
MCITP
|
Да, забыл отметить, что спастись в данной ситуации можно (ну кроме новой переменной, иссестна ) можно посредством
X++: <tableBuffer>= null;
__________________
Zhirenkov Vitaly |
|
|
За это сообщение автора поблагодарили: Logger (2). |
25.12.2008, 00:27 | #5 |
Administrator
|
Цитата:
Ну а если Ваш эффект исправили - значит все-таки действительно решили что баг. А за предостережение - спасибо. Все-таки повод лишний раз проверить код
__________________
Возможно сделать все. Вопрос времени |
|
Теги |
курсор |
|
Похожие темы | ||||
Тема | Ответов | |||
Все же - приколы KR 1-3 | 0 | |||
Приколы нашей системы - импорт объектов | 4 | |||
Курсоры | 20 |
|