![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Insert, Update, Delete своими руками [D7, MSSQL]
mvg_first © (2004-01-19 16:40:00)
Добрый день мастера и остальные.
Заранее прошу прощения за возможно-банальный вопрос, но я настолько давно не общался с сообществом Delphi-программистов что правильно впорос поставить сейчас и не смогу. Поэтому прошу отнестись с пониманием и "больно не пинать"
Суть задачи.
Я пробую разрабатывать приложение для работы с БД MSSQL2000/ Для этого использую компоненты TADQQuery. В качестве контролов использую стандартный DBGrid.
Но сложность заключается в том что я хочу все запросы на вставку, добавление и удаление записей из отображаемых таблиц - делать самостоятельно. Т.е. когда пользователь добавляет в Гриде запись и пробует ее записать - что бы каким-то образом получить доступ к изменившимся полям выполнить операцию по вставке и если не случилось ошибки дать пользователю возможность работать с программой дальше, а в случае ошибки отменить вставку строки (вомзожно с выводом сообщения).
Компонет реализующий очень похожую функциональность в Делфи есть это TUpdateSQL - но он работает только с BDE версиями компонентов доступа к данным. Я же хочу использовать технологию ADO.
Пожалуйста порекомендуйте литературу (интеренет ресурсы), компоненты, образцы исходного кода - проработав которые я смогу самостоятельно разобраться и решить поставленную задачу.
Если к кому нибудь из Вас можно обратится посредством ICQ буду очень признателен (мой ICQ 84705448)
mvg_first (2004-01-27 13:31:00) [41]
Тут порекомендовали использовать View на сложные таблици и INSTEAD OF тригерры - но попробовал и получается чепуха какая то. Если я из Query Analizer выполняю инсерт то триггер отрабатыавет как и задумаывалось. А если я загоняю селект из этой вьюхи в обыкновенную ADOQuery то при добавлении записи выполняется инсернт непосредственно в таблицу на которую смотрит View??? Никто с таким не сталкивался?
mvg_first (2004-01-21 11:06:00) [42]
В процессе длительних ковыряний (вчера до часу ночи сидел) пришел к выводу что один из "человеческих" вариантов - это написать свой потомок TADOCustomDataSet и переопределить в нем метод InternalPost. Вызывая Refresh - у объекта RecordSet (тот который чиста адошный)
KSergey (2004-01-21 08:48:00) [43]
Off
Вот, я же говорил: идет множество очевидных предложений не по сути, как только в лоб спрашиваешь "так как же в конце концов" (см., например, ответ mvg_first для Arm79) - так все...
To > [9] Petr V. Abramov © (19.01.04 17:49)
> Технология 100% рабочая, испробованная, но если ее использовать
> "в лоб", т.е. со стандартным Дельфовым набором компонентов,
> требует много ручного труда, причем именно ручного, а не
> умственного
Может вы все же сможете поделиться 100% рабочей технологией с общественностью? Любой. Хоть в лоб. хоть по лбу - уже не важно ;)
(не хотелось бы думать, что уверения про 100% были просто для красного словца...)
> [22] mvg_first © (20.01.04 16:13)
> KSergey
> не соблаговолите ли Вы известить о результатах меня?
Забуду, стопудово.
Максимум что могу обещать - опубликовать на этом форуме.
mvg_first (2004-01-20 17:42:00) [44]
Arm79
Краткий алгоритм в студию!!!
Основная проблема при выполнении изменений в гриде - недать датасету выполнить внутренний запрос к БД - как это решается с помощью ADOCommand?
Arm79 (2004-01-20 16:51:00) [45]
Собственно говоря, я немного не понял. Зачем столько мути? Вместо UpgateSQL предлагаю использовать ADOCommand в режиме Command
Text.
mvg_first (2004-01-20 16:13:00) [46]
Плохиш_
Такой банальный вариант - давно эксплуатируется - меня не устравивает - мне нужно пользователю предоставить изменение менно в гриде данных - ибо данные однотипного образца и скорость ввода данных в гриде будет выше.
DenK_vrtz
Мне не нужно контроллировать логику работы БД (вернее конкретно в этом вопросе) мне нужно самостоятельно составить запрос и не дать этот запрос сделать ADO-шному датасету.
И поэтому никаких временных таблиц дополнительных транзакций и прочего не нужно. В бд уже есть своя логика завязанная на многих факторах и только из-за того что клиентское приложение не может правильный запрос послать - я ее переделывать не собираюсь.
KSergey
Присоединяюсь к Вам в поисках решения по этому вопросу. Если вдруг поиски увенчаются успехом и результат не будет ноухау - не соблаговолите ли Вы известить о результатах меня?
To ALL
Вопрос не закрываю и буду рад дальнейшим предложениям и советам.
KSergey (2004-01-20 15:12:00) [47]
> [20] DDP1 (20.01.04 13:27)
А это да, это есть такое.
Правда, в подобных случаях меня всегда смущает фраза "Это может способствовать быстрому переводу программ с BDE на ADO". Как я понимаю, автор хочет сказать, что это решение "для ленивых", вроде как и без этого можно обойтись...
Ну либо я напрасно так это все понимаю.
DDP1 (2004-01-20 13:27:00) [48]
KSergey © (20.01.04 12:40) [19]
А вто статья есть
http://www.delphikingdom.com/treasury/adocomp.htm
Я правда не разбирался
KSergey (2004-01-20 12:40:00) [49]
> [16] Плохиш_ (20.01.04 11:04)
> 1. grid.readonly := true
А если надо именно как раз grid.readonly := false?
> 4. Думалка.Active := true
Этой темой интересуюсь давно, однако постоянно вижу одно и тоже: рассказывают очевидные в принципе вещи про то, что сесть надо на BeforeUpdate/Insert и отсылать свой запрос.
Но как только касается как раз самого узкого места "как же заставить не отправляться запрос движком ADO, однако обновить DataSet" - тут же либо молчок, либо что-то невразумительное, либо думай сам, "ноу-хау". Так остальное - оно и так очевидно!!! Дак уж разжуйте хоть раз до конца, хоть кто-нибудь, "ну что вам, трудно чтоли?"!
Вот и Petr V. Abramov утверждает, что у него "Технология 100% рабочая", однако тоже недосказывает... Хотя пока надежды не теряю услышать его комментарии.
> [18] DenK_vrtz © (20.01.04 11:52)
> Сергей, или я сути вопроса не понимаю?
Этого я не знаю ;)
Впрочем, как писал уже не один раз - самое узкое место для меня и до сих пор не понятое - "как заставить не отправляться запрос движком ADO, однако обновить DataSet". А то, что логику можно проверить на сервере - это не суть важно, на мой взляд. Т.е. и так понятно, что раз я сам формирую запрос на изменение данных - то это может быть что угодно. И под словом "контролировать" понимается, как я думаю, не контроль за целостностью данных, а контроль за отправляемыми запросами на сервер.
Я пока вижу лишь один способ обновлять DataSet: рефреш записи, однако если для модифицируемой записи это еще выполнимо, то для вновь вставленной - переоткрывать весь DataSet? Как-то не очень это здорово, по-моему... А как иначе - не знаю я...
> [15] DDP1 (20.01.04 10:51)
> пишем
> SELECT * into #t From TESTTABLE1 T1
> JOIN TESTTABLE2 T2 ON T1.KOD=T2.KOD
> select * from #t
Да, предложение так же не ново. Можно, факт. Можно даже создавая временнубю таблицу сразу создавать и тригера, которые будут прямо на сервере править реальные таблички, вот только как-то через чур заумно получается, на мой взгляд. Хотя многие проблемы действительно можно решить. С другой стороны - тогда уж проще вообще табличку в памяти организовать - получится точно менее ресурсоемко при той же функциональности.
Причем, что досадно, ну была же у борланда шикарная технология с UpdateSQL! Ну ведь действительно прекрасно придумано. А в ADO - ну нету такого и все... Хотя я и понимаю, что UpdateSQL - чисто борландовская примочка. К слову сказать, в библиотеке VGLibrary есть ADO-компоненты и именно с UpdateSQL. Но давно она что-то не развивается уже.
DenK_vrtz (2004-01-20 11:52:00) [50]
>KSergey ©
>Высказывание не по теме
>Речь идет не о контроле целостности, а о контроле над
>отправляемыми запросами по модификации данных, которые
>(запросы) ADO тщательно пытается от нас сокрыть.
не согласен!
Смотрим [11].
Логику ввода данных реально проверять на сервере, а не заниматься эти на клиете. Я не прав?
Сергей, или я сути вопроса не понимаю?
KSergey (2004-01-20 11:14:00) [51]
> [14] DenK_vrtz © (20.01.04 10:15)
> >Как тут быть? Как контроллировать логику добавления записей?
>
> а все на сервере нельзя контролировать?
> ключи, индексы, обработчики ошибок, триггера и т.д.
Высказывание не по теме
Речь идет не о контроле целостности, а о контроле над отправляемыми запросами по модификации данных, которые (запросы) ADO тщательно пытается от нас сокрыть.
> [9] Petr V. Abramov © (19.01.04 17:49)
> В BeforePost выполняете Update/Insert-запросы ( в зависимости
> от Dataset.State), в BeforeDelete - Delete-запрос. Если
> Insert/Update-запрос возвращает какие-то параметры,
Не совсем понял о каких параметрах речь. Уточните, пожалуйста.
их "еще
> не поздно" просто подставить в соотвествушие поля DataSet`а.
> Если возникает exception - у пользователя не получится уйти
> с записи, не исправив свои ошибки ввода или не отменив ввод.
> Технология 100% рабочая, испробованная, но если ее использовать
> "в лоб", т.е. со стандартным Дельфовым набором компонентов,
> требует много ручного труда, причем именно ручного, а не
> умственного
Вслед за mvg_first хочется спросить: "как сформировав и выполнив свой запрос не дать выполнится инсерту по дефолту проходящему в Дата сете"??
[13] Academic © (20.01.04 10:00)
Повторяю...
Даже если на BeforePost, после Abort, данные
в DBGrid пропадут, изменения уже прошли в базу.
Достаточно сделать Refresh данных, и они отобразятся.
Refresh - это если запись у меня уже етьс (если о рефреше одной записи речь). А если она добавилась - как клиентская часть может этот рефреш сделать? Или имеется в виду переоткрыть запрос? На каждую запись? Не слишком ли накладно? Или я что-то недопонял?
Давно мне еще помнится как-то кто-то советовал такой метод: включить BatchUpdate, тогда ADO не посылает запросы, пока не вызвать какой-то там метод (не помню, ну да не важно). Предлагалось сыграть на этом (т.е. вызывать CancelBatch). Вот только на вопрос "дак а как данные-то в DataSet запихнуть, да чтобы еще на сервер новый назрос не ушел" - был дан атвет "а это ноу-хау"...
Так я и не знаю до сих пор как это сделать.
Плохиш_ (2004-01-20 11:04:00) [52]
>mvg_first
1. grid.readonly := true
2. на форму кнопки insert, edit, delete
3. форму для ввода данньх
4. Думалка.Active := true
DDP1 (2004-01-20 10:51:00) [53]
Есть предложение. Вместо
SELECT * From TESTTABLE1 T1
JOIN TESTTABLE2 T2 ON T1.KOD=T2.KOD
пишем
SELECT * into #t From TESTTABLE1 T1
JOIN TESTTABLE2 T2 ON T1.KOD=T2.KOD
select * from #t
отлавливаем все измения во временной табличке, пишем свои изменения в реальные таблички.
DenK_vrtz (2004-01-20 10:15:00) [54]
>Как тут быть? Как контроллировать логику добавления записей?
а все на сервере нельзя контролировать?
ключи, индексы, обработчики ошибок, триггера и т.д.
Academic (2004-01-20 10:00:00) [55]
Повторяю...
Даже если на BeforePost, после Abort, данные
в DBGrid пропадут, изменения уже прошли в базу.
Достаточно сделать Refresh данных, и они отобразятся.
mvg_first (2004-01-20 09:30:00) [56]
Больше предложений не поступит? Только через BeforePost?
Попоробовал BeforePost - но так и не понял как сформировав и выполнив свой запрос не дать выполнится инсерту по дефолту проходящему в Дата сете
mvg_first (2004-01-19 18:24:00) [57]
А на вопрос зачем мне это все - изначально я хотел работать на хранимых процедурах и селекты и инсерты и апдейты делать на них - но потом просто захотел решить этот вопрос для себя кардинально.
Т.е. я хочу сам управлять изменением записей на сервере. Тем более не всегда возможно отдать на откуп обновление данных датасету. Ведь могут быть сложные конструкции селектов с разветвленными Join-ами и сложными условиями.
Как тут быть? Как контроллировать логику добавления записей?
mvg_first (2004-01-19 18:01:00) [58]
А какие могут применяться нестандартные компоненты облегчающие задачу? Ибо мне предстоит работать с большим количеством разнообразных таблиц. И не хочется для каждой из них много механического труда применять если есть возможность это обойти
Petr V. Abramov (2004-01-19 17:49:00) [59]
В BeforePost выполняете Update/Insert-запросы ( в зависимости от Dataset.State), в BeforeDelete - Delete-запрос. Если Insert/Update-запрос возвращает какие-то параметры, их "еще не поздно" просто подставить в соотвествушие поля DataSet`а. Если возникает exception - у пользователя не получится уйти с записи, не исправив свои ошибки ввода или не отменив ввод.
Технология 100% рабочая, испробованная, но если ее использовать "в лоб", т.е. со стандартным Дельфовым набором компонентов, требует много ручного труда, причем именно ручного, а не умственного
Academic (2004-01-19 17:37:00) [60]
> А вызов Abort не отменит ли саму операцию инсерта как таковую?
> Почему то мне кажется как только я сделаю вызов Abort -
> на гриде добавляемая запись просто исчезнет потому как датасет
> ему скажет что операция отменена?
Блин, ну я торможу...
Тебе не все равно что она отменится?
Ты же делаешь Refresh?