Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2007.06.03;
Скачать: [xml.tar.bz2];

Вниз

Обновление автоинкремента в мёртвых запросах   Найти похожие ветки 

 
Sour Smile   (2007-03-14 14:20) [0]

В DBGrid1 отображаются данные из Query1.
Запрос элементарный: "SELECT Id, Field1, Field2 FROM Table1 ORDER BY Field1" (Id - автоинкрементное поле, предназначенное для задания уникальности каждой записи, а Field1 и Field2 - собственно поля с данными).
Тем не менее использование оператора "ORDER BY" делает этот запрос мёртвым (т.е. нередактируемым даже при установленном в True свойстве RequestLive). Собственно об этой плохой особенности оператора "ORDER BY" сказано в справке по LocalSQL.
Поэтому, чтобы пользователь всё же мог редактировать данные в гриде, приходится устанавливать в True свойство CachedUpdates и подключать к Query1 компонент UpdateSQL1.
Запросы в UpdateSQL1 тоже элементарные:
1) вставка: "insert into Table1 (Field1, Field2) values (:Field1, :Field2)"
2) модификация: "update Table1 set Field1 = :Field1, Field2 = :Field2 where Id = :OLD_Id"
3) удаление: "delete from Table1 where Id = :OLD_Id"

Для того чтобы после изменения или удаления пользователем каждой записи, данные из кэша применялись собственно в таблицу, на событиях "AfterPost" и "AfterDelete" у компонента "Query1" прописан код: Query1.ApplyUpdates; Query1.CommitUpdates

Теперь собственно описание проблемы: когда пользователь добавляет новую запись, вносит в неё данные и применяет изменения (Post), новая запись с введёнными данными действительно добавляется в таблицу, однако в гриде автоинкрементное поле остаётся пустым (в самой таблице естественно в него записывается некоторое значение).

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

Однако, предположим, что пользователь заметил ошибку и решил подредактировать только что введённую запись и вот теперь, после нажатия Post вылетает ошибка: "Update failed"... И это можно понять: ведь в запросе на обновление указано, что "update ... where Id = :OLD_Id", но ведь OLD_Id пустое (!).

По той же причине будет ошибка и при удалении этой записи. И совсем наоборот: и обновление и удаление прекрасно работают если запись была добавлена ранее, до последнего "Query1.Open". Но переоткрывать запрос после каждой вставки нехорошо, да и нужно после переоткрытия спозиционировать фокус ввода на вновь добавленную запись, а как же спозиционируешь, если неизвестно значения его поля "Id"...

Как же заставить обновлять автоинкрементное поле в кэше при вставке новой записи?


 
Sergey13 ©   (2007-03-14 15:07) [1]

AutoRefresh - это не оно?


 
Johnmen ©   (2007-03-14 15:12) [2]


> Как же заставить обновлять автоинкрементное поле в кэше
> при вставке новой записи?

После ApplyUpdates, если не было ошибок, кэш пуст. Это так, к слову....
А вот в наборе данных "увидеть" ID - только перезапрашивать НД (close-open) при тех условиях, которые приведены (Paradox+BDE).
Извращения не рассматриваем...


 
Desdechado ©   (2007-03-14 15:22) [3]

> Но переоткрывать запрос после каждой вставки нехорошо,
Однако сохранять каждое изменение каждой записи отдельно ты почему-то не считаешь дурным тоном:
> на событиях "AfterPost" и "AfterDelete" у компонента "Query1" прописан код: Query1.ApplyUpdates; Query1.CommitUpdates

Обычно сохраняют изменения пачкой, когда пользователь все наредактировал, что ему хотелось, и нажал "сохранить". Тут и переоткрыть запрос не грех. Заодно увидишь, как изменился порядок записей, если он редактировал сортируемые поля.


 
Sour Smile   (2007-03-14 16:09) [4]


> Sergey13 ©   (14.03.07 15:07) [1]
> AutoRefresh - это не оно?
Ксожалению AutoRefresh на мёртвых запросах не работает (об этом вроде тоже в справке есть).


> Desdechado ©   (14.03.07 15:22) [3]
> > Но переоткрывать запрос после каждой вставки нехорошо,
>
> Однако сохранять каждое изменение каждой записи отдельно
> ты почему-то не считаешь дурным тоном:
> > на событиях "AfterPost" и "AfterDelete" у компонента "Query1"
> прописан код: Query1.ApplyUpdates; Query1.CommitUpdates
>
> Обычно сохраняют изменения пачкой, когда пользователь все
> наредактировал, что ему хотелось, и нажал "сохранить". Тут
> и переоткрыть запрос не грех. Заодно увидишь, как изменился
> порядок записей, если он редактировал сортируемые поля.

Переоткрывать после каждой вставки дурной тон, так как: 1) после этого необходимо спозиционироваться на эту запись (а как это сделать, если неизвестно Id вновь вставленной записи?); 2) таблица огромная (более 70 мегабайт и продолжает расширяться) и на каждое её открытие уходит масса времени (разве не дурной тон? а так у пользователя есть кнопка по которой он может её переоткрыть в любой момент для пересортировки)

Первоначально у меня пачками и обновлялись записи, однако и тут я столкнулся с некоторыми проблемами и в первую очередь с тем что пользователь за один сеанс может ввести 100 или 1000 записей и все эти введённые данные могут не примениться из-за одной ошибочной записи из этой "пачки"... (я ещё жить хочу :). Вторая же проблема в том, что мне в любой момент нужно знать Id текущей записи.


 
Sergey13 ©   (2007-03-14 16:26) [5]

> [4] Sour Smile   (14.03.07 16:09)
Дурной тон работать с такими объемами в Парадоксе и брать всю таблицу сразу, да еще с сортировкой.


 
Mike Kouzmine ©   (2007-03-14 16:39) [6]

Можно сделать индекс по филду1, открыть ттайблем, установив ему indexname := пофилду1 и добавлять. Все ид после пост будут видны.


 
Sour Smile   (2007-03-14 17:32) [7]


> Sergey13 ©   (14.03.07 16:26) [5]
> > [4] Sour Smile   (14.03.07 16:09)
> Дурной тон работать с такими объемами в Парадоксе и брать
> всю таблицу сразу, да еще с сортировкой.

Если речь зашла о дурном тоне, то лично я вообще считаю дурным тоном работать через BDE. К счастью по работе мне не приходится с ним работать - моя основная среда работы с базами: MSSQL (через ADO). В MSSQL таких простецких вопросов не возникло бы (при "order by" возвращаются живые, редактируемые данные). А если бы и возникло думаю и их обошёл бы.

Например, одна из проблем в моём вопросе (это также и проблема компонента TUpdateSQL), как узнать какое значение получило поле Id (автоинкрементное) после добавления новой записи (т.е. "insert into ...")и я думаю что эту проблему (нормальными способами) в BDE к сожалению решить нельзя. А вот в MSSQL достаточно изменить запрос для добавления новой записи на такой: "insert into Table1 (Field1, Field2) values (:Field1, :Field2) select @@identity" и если открывать его не через ADOQuery1.ExecSQL, а через ADOQuery1.Open, то добавится новая запись и откроется датасет с единственным полем и единственной записью в котором собственно и будет идентификатор (т.е. значение автоинкрементного поля)  добавленной записи (узнать его элементарно: ADOQuery1.Fields[0].AsInteger)

Однако это отклонение от сути вопроса


 
Desdechado ©   (2007-03-14 17:55) [8]

> Переоткрывать после каждой вставки дурной тон, так как:
Кто тебе говорил о переоткрытии после каждой? Я тебе говорил о переоткрытии после сохранения (одного на пачку).
Ку?

> пользователь за один сеанс может ввести 100 или 1000 записей
> и все эти введённые данные могут не примениться из-за одной
> ошибочной записи из этой "пачки"
Глупости. Сохранять их можно и по одной (каждая в своей транзакции, а не все в одной транзакции), но по команде пользователя, а не автоматом.
Или у тебя все данные взаимозависимы (первая запись не прошла, остальные уже не смогут из-за логической завязки на предыдущие)?

И работать с данными надо по критериям, а не как с физической таблицей "более 70 мегабайт и продолжает расширяться".

Sour Smile   (14.03.07 17:32) [7]
Это реклама АДО? Чего ж не пользуешься?


 
Mike Kouzmine ©   (2007-03-14 18:03) [9]

Для работы с парадоксом адо лишняя надстройка. Работа идет через бде. Гораздо функциональнее и проще работать с родными для этого формата компонентами, а именно TTable из вкладки БДЕ.



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2007.06.03;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.04 c
2-1178960077
mr1Andersen
2007-05-12 12:54
2007.06.03
Что можно(нужно) сделать, чтобы Delphi запомнил


2-1179232495
NotAva
2007-05-15 16:34
2007.06.03
сообщение на перерисовку


11-1160821604
vampir_infernal
2006-10-14 14:26
2007.06.03
Exception, TNotifyEvent и не только


2-1178898796
M1sT
2007-05-11 19:53
2007.06.03
Ошибка при выполении SQL запроса....


15-1178889904
ArtemESC
2007-05-11 17:25
2007.06.03
Мистика... Видимо вопросы по PHP можно задавать только здесь...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский