Форум: "Базы";
Текущий архив: 2002.02.07;
Скачать: [xml.tar.bz2];
ВнизНужен совет в подходах работы с БД Найти похожие ветки
← →
kserg@ukr.net (2002-01-08 12:59) [0]С Новым годом Всех! Хочу выяснить у уважаемых коллег какие есть
подходы в технике работы с клиент-серверной БД.
Поясню.
Один из подходов (пользуюсь им сам) следующий:
работа с таблицами только через TQuery (полный отказ от TTable).
Т.е. формирую запрос со всеми наворотами WHERE-GROUP-ORDER,
выполняю его и "гоню" в GRID.
Как правило, в GRID вытягиваю данные из нескольких связанных таблиц.
Соот-но операции Add/Edit в GRIDe делаю недоступными и выполняю их через
вспомаг.окношко, где есть все нужные поля при заполнении котр. использую
всякие "примочки" для ускорения-удобства ввода инфо юзерами.
Затем выполняю входной контроль данных
(как правило, чтобы ключевые поля не были пустыми)
и только после этого формирую соот-щий запрос Insert/Update.
После успешной операции остается только переоткрыть
рабочий набор данных
(сталкнулся с ситуациями, когда метод REFRESH не всегда срабатывал,
поэтому пришлось тупо делать TQuery.Close; TQuery.Open;)
Подход жёсткий в плане интерфейса, но надежный в плане конфликтов при вводе
данных несколькими юзерами одновременно.
Но, пользователям не всегда нравиться такая сложная схема.
Многие хотят вести правку прямо в GRIDe.
И здесь мне не совсем ясно, как реализовать такой подход
(правка прямо в GRIDe), когда запрос выполняется по 2-3-4 связанным таблицам?
Хотелось бы услышать, какие еще подходы работы получили распространение.
Заранее благодарен.
Сергей
← →
Romkin (2002-01-08 13:30) [1]Для двухзвенки - подход практически единственно правильный, все так делают, разняться только проверки полей (иногда в триггере, со своими exception). Все остальное - тормознее, хотя и удобнее
Могу посоветовать TUpdateSQL - при включении CashedUpdates сам будет вгонять в базу, и запрос можно будет редактировать :-)) правда, вопрос, что делать с полями из других таблиц..., обычно lookup поля не селектишь, а организуешь в гриде
Но можно применять смешанно.
Можно также использовать связку TDataSetProvider + TClientDataSet, там делай, что хошь. Но в результате все равно приходишь к схеме Список - Форма редактирования, по OK - закачка.
← →
panov (2002-01-08 13:32) [2]1. Объяснить пользователям, что если они хотят терять и перебивать свои данные по 10 раз, то можно сделать так, как они хотят.
2. Воспользоваться TTable, и все корректировки выполнять в транзакциях. После окончания спрашивать у пользователей, хотят ли они сохранить то, что напортили в БД, или нет.
3. Пользоваться UpdateSql...
← →
kaif (2002-01-09 01:00) [3]Можно впролне надежно редактировать и в Grid-е. Нужно поставить UpdateSQL или заглушку какую-то вместо него, или вписать в него что-нибудь, чтобы не ругался, что нет соответствующих запросов, затем вписать в обработчик BeforePost самого DataSet код, создающий TQuery runtime и так можно кучу таблиц сразу апдейтить. В обработчике BeforePost можно в конце Abort вписать, чтобы не выполнялись тексты, вписанные в UpdateSQL.
Еще проще, если режим CashedUpdates использовать. Тогда можно все руками прописать.
Хотя неужели пользователю нужно апдейтить сразу множество таблиц?...
← →
Desdechado (2002-01-09 10:19) [4]я извлекаю практически во всех формах данные через хранимые процедуры (просто очень навороченные запросы получаются), засовываю в грид, даю пользователю редактировать (иногда прямо в гриде, иногда отдельно), а сохраняю опять при помощи хранимой процедуры, которая распихивает все данные по нужным таблицам с нужными операциями (INS, DEL, UPD). Она же прописана во всех 3 SQL компонента UpdateSQL.
Очень удобный подход - все вынесено на сервер, клиентское приложение не заморочивается всеми нюансами.
← →
Сергей Иванов (2002-01-09 13:11) [5]Полностью согласен с Desdechado. Romkin, почему же единственно правильный именно этот подход? Он скорее наиболее прост, т.к. позволяет обходится стандартными компонентами.
Может, я не прав, но зачем клиенту перечитывать базу, если все, что он внес в гриде (я использую в основном TStringGrid и TListView для этих целей) он может видеть прямо здесь, не отходя от кассы. Если хранимая процедура отработала успешно, то просто переписываем значения ячеек в гриде. Сложнее уведомить всех остальных об изменениях (используем своего рода callbacks для рассылки сообщений всем заинтерисованным клиентам), но это можно сделать. К тому же, для заполнения гридов и форм мне нужны просто связанные списки, например название фирм+заказы+дата заказа. Получим его при помощи IStrings и заполним грид - тем самым заставив сервер перебирать Query, а не сливать это на клиента и гонять его там. Не думаю, что оператору нужно знать ID записи, ее Relation и прочее. Заслав на сервер в процедуре всего пару-тройку уникальных параметров (которые позволят идентифицировать заказ на самом сервере) и изменение/дополнение/создание заказа в еще одной хранимой процедуре (имена товаров+кол-во; сервер сам найдет их ID, наличие на складе, вес, упаковку и т.д.) и вернет нам except - если нету или чего еще.
← →
Сергей Иванов (2002-01-09 13:19) [6]PS.
"Почему именно связанные списки, ведь есть же база данных и запросы. Там ведь все связано" - сказал мне шеф.
"Потому что это дельфишные TTable(TQuery)+TDataset+TDataLink, тормозящие даже при простом пролистывании (не редактировании!) грида, модуль DBTables, модуль DB, и еще наверняка - BDE на клиенте". Клиент опухает, и намного. А в этом случае он пуст, как бамбук.
← →
kaif (2002-01-09 13:32) [7]В любом случае стоит переносить все на сервер. Совершенно согласен. К тому же в хранимых процедурах легче администрировать доступ. Например, делаем:
GRANT UPDATE ON TABLE1 TO PROCEDURE PROCEDURE1;
GRANT UPDATE ON TABLE2 TO PROCEDURE PROCEDURE1;
GRANT UPDATE ON TABLE3 TO PROCEDURE PROCEDURE1;
Затем пользователю нужно только прописать один GRANT:
GRANT EXECUTE ON PROCEDURE PROCEDURE1 TO USER1;
К тому же можно прямо в процедурах использовать имя пользователя, причем в процедуре, которая делает SELECT, например:
FOR SELECT ... FROM TABLE1
WHERE USER=DOCUMENT_CREATOR
INTO ...
DO SUSPEND;
Для этого достаточно в таблице завести поле DOCUMENT_CREATOR и вписывать туда значение системной переменной USER в триггере перед вставкой.
Вообще не следует администрирование прав оставлять на самый последний момент - лучше продумать все это заранее.
← →
evgeg (2002-01-09 13:32) [8]> И здесь мне не совсем ясно, как реализовать такой подход
(правка прямо в GRIDe), когда запрос выполняется по 2-3-4 связанным таблицам?
Можно, например сделать компонент TUpdateScript, который на каждое действие будет выполнять несколько запросов.
Симпатичен подход Desdechado, хотя процедур будет многовато.
← →
Romkin (2002-01-09 15:11) [9]2Сергей Иванов
Постепенно начинает появлятся требование видеть не только то, что сам сделал, но и результаты работы других клиентов, а это быстрее всего перечитыванием (для стандартных компонент). То, как у тебя - все ручками... Мне, например, нравится MIDAS - тоже клиент пуст, и при этом все автоматом, ну почти все. А насчет callback... Тяжко - встает вопрос о синхронизации потоков (очередь уведомлений), о том, как показывать (пользователю не очень приятно, когда данные перечитываются как только надо), опять же возникнут вопросы типа "А почему ошибка? у меня в списке не занято..." (на другой станции уже заняли...) - опять же для проверки обращаешься к базе. ТАк что еще вопрос, что удобнее - постоянное обновление после редактирования или по уведомлению
← →
Сергей Иванов (2002-01-10 11:17) [10]Конечно постоянное обновление удобнее. И проще в реализации. Но при количестве клиентов ~>5 начнаются тормоза. На чем бы не крутилась база.
Парус8 видел? Oracle8i+Delphi5. Интрефейс (для всего - и документов, и журналов, и...) - TreeView слева, два грида (один над другим) справа. Гриды - наследники TDBGrid. Так вот там больше всего времени (и траффика, и ресурсов сервера) занимает как раз перечитывание датасетов даже при простом листании TreeView. Скорее всего реализация такова: выбрали TreeNode -> Locate(MasterData) -> в нижнем гриде - DetailData перечитывается с сервера. При проходе по строчкам Master -> перечитывание Detail. И прочее, прочее, прочее :(
А ведь если вдуматься, чаще всего детальные данные и не нужны, как впрочем, и бОльшая часть основных. Как и связанное представление в 2-3 гридах - это просто неудобно для оператора. У меня операторы долбят по клаве не глядя на содержимое - товара, организации, контрагента - они это помнят как "отче наш". При необходимости - пжлста. Перечитаем Detail.
Вот такие вот дела. Мда... Много чего еще хотелось бы сказать :) да писАть лень :( Это тема для объемного разговора, если не статьи.
← →
Romkin (2002-01-10 11:55) [11]Полностью согласен, чаще всего дает организация интерфейса: чем он красивее, тем больше тормозов. У меня давно интерфейс в виде простого списка, с фильтром (чаще всего по периоду), количество записей зависит от фильтра, если юзверь его убрал - сам виноват, что ждет несколько минут, в руководстве это помянуто. Результат - спокойная работа по модему. Обновление идет либо по кнопке, либо после редактирования. А детальные данные только по заказу, они действительно не нужны, всегда можно сделать еще список, в котором связка detail->master
← →
kserg@ukr.net (2002-01-10 12:01) [12]Благодарю всех за интересную дискуссию
(теперь мне "пищи" для размышлений хватит на долго)
Отдельно хочу сказать спасибо >Romkin - выручает меня уже не первый раз.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2002.02.07;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.005 c