greyich |
Отправлено: 12.08.2005, 08:41 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 45
|
QUOTE (olegenty @ 12/08/2005, 08:36) | возможно, тебе поможет какая-то из этих строк (или их комбинация):
CODE |
MemTable->FieldDefs->Update();
MemTable->FieldDefList->Update();
MemTable->FieldList->Update();
|
Persistent полей, я надеюсь, у тебя там нет? |
написал даже все три сразу — непомогло. конечно попробую комбинации но боюсь вряд ли поможет
перепробовал все 7 комбинаций тоже не помогло
Отредактировано greyich — 12/08/2005, 08:46
|
|
AVC |
Отправлено: 12.08.2005, 08:54 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE (greyich @ 12/08/2005, 07:35) |
1. а еще лучше на FindField
а) несколько не понял что значит "обернуть sql_text в еще один select". не могли бы вы пояснить подробнее
б) другими словами adoquery не рулит и рекомендуется пользоваться хранимыми?
|
1. В приведенном вами коде не лучше, так как вы все равно получите исключение при доступе к Value. Это лучше когда создаются переменные под поля.
А с учетом 2 это вообще безразлично.
а) Select * From (+ sql_text + ) Where id = :id
б) Это проверять вам. Лично я пользуюсь запросами а не SP.
QUOTE (greyich @ 12/08/2005, 07:35) |
кстати текст записанный в
ADODataDriverEh1->GetrecCommand->CommandText->Text сработал только после вызова RefreshRecord. на все остальные попытки, как например закрыти и открытие набора данных и сетки, он молчал в тряпочку.
|
Судя по названию свойство GetRecCommand именно для этого и предназначено (RefreshRecord). И молчал в тряпочку в остальных случаях он вполне справедливо.
PS.
Замечания были общего характера, безотносительно к MemTable и EhLib (ну не пользуюсь я ими, своего хватает ). Но мне кажется, что у вас где-то ошибка в логике. В конце концов пройдитесь по шагам, посмотрите протокол обмена с сервером.
|
|
olegenty |
Отправлено: 12.08.2005, 09:18 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
вот и я думаю — что где-то ошибка в логике. у меня же работает, как мне хочется
|
|
greyich |
Отправлено: 12.08.2005, 09:26 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 45
|
QUOTE (olegenty @ 12/08/2005, 09:18) | вот и я думаю — что где-то ошибка в логике. у меня же работает, как мне хочется |
как в старом анекдоте:
- Где у меня ошибка?
- В ДНК!
ладно будем укрощать. может ли это из-за того что не все commandEh заполнены? (за ненадобностью).
|
|
olegenty |
Отправлено: 12.08.2005, 09:31 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
нет, не может. если требуется некий Command, SQL которого пуст, возникает вполне конкретное сообшение об ошибке, которое и вещает — "мне надо, а нету... разберитесь..."
|
|
greyich |
Отправлено: 12.08.2005, 09:54 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 45
|
QUOTE (olegenty @ 12/08/2005, 09:31) | нет, не может. если требуется некий Command, SQL которого пуст, возникает вполне конкретное сообшение об ошибке, которое и вещает — "мне надо, а нету... разберитесь..." |
хм. еще раз прочитав справку узрел я, что наверное обработчик события onRefreshRecord надо писать мне. и куда я раньше смотрел?
осталось понять что туда писать и чем оно отличается от первичного заполнения даными
|
|
olegenty |
Отправлено: 12.08.2005, 10:00 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
стоп!!! так ты в GetrecComand хотел поле добавить??? не-е-е-е-е... поле можtn быть добавлено только посредством SelectComand.
далее. если написать OnRefreshRecord, то GetrecCommand и обновление по умолчанию будут игнорироваться нафиг. (хотя ты легко сможешь ими воспользоваться самостоятельно). проинициировав событие, ты и сам увидишь, что там всё просто, как дверная ручка. пример надо?
|
|
greyich |
Отправлено: 12.08.2005, 10:07 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 45
|
QUOTE (olegenty @ 12/08/2005, 10:00) | стоп!!! так ты в GetrecComand хотел поле добавить??? не-е-е-е-е... поле можtn быть добавлено только посредством SelectComand.
далее. если написать OnRefreshRecord, то GetrecCommand и обновление по умолчанию будут игнорироваться нафиг. (хотя ты легко сможешь ими воспользоваться самостоятельно). проинициировав событие, ты и сам увидишь, что там всё просто, как дверная ручка. пример надо? |
???? обана. поле я добавляю вообще без обработчиков событий dbgrideh! на кнопке у меня висит добавление поля. а потом я уже пытаюсь проадейтить datadrivereh и memtableEh. а что неправильно???
надо спровоцировать в обработчике нажатия кнопки какое-то событие?
|
|
olegenty |
Отправлено: 12.08.2005, 10:36 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
ну ты перец!!! поле надо добавлять в TMemTableEh, грид-то тут при чём?
|
|
greyich |
Отправлено: 12.08.2005, 10:54 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 45
|
QUOTE (olegenty @ 12/08/2005, 10:36) | ну ты перец!!! поле надо добавлять в TMemTableEh, грид-то тут при чём? |
блин да не перец я не перец!
поле добавляю в базу! так давайте еще раз но пошагово:
главные герои: форма, на ней DBGridEh, к нему присоединены Datasource, MemTableEh и наконецто DAtaDriverEh.
сцена первая:
формирую sql запрос текстовой строкой и кидаю в
ADODataDriverEh1->SelectCommand->CommandText->Text = sql_text;
потом
MemTableEh1->Active = true;
и после
ADODataDriverEh1->GetrecCommand->CommandText->Text = sql_text + " where id_p = '" + MemTableEh1->FieldByName("id_p")->asString;
на форме видим заполнение сетки данными(что вполне логично )
сцена вторая: наступает после попыток юзверя ввести что-нибудь в ячейку
на сцену вызывается DODataDriverEh1UpdateRecord
к которому у меня приписана хранимая процедура
dm_ado->gr_update_exams_sp->Close();
dm_ado->gr_update_exams_sp->Parameters->operator [](1)->Value = val;
dm_ado->gr_update_exams_sp->Parameters->operator [](2)->Value = fio;
dm_ado->gr_update_exams_sp->Parameters->operator [](3)->Value = subj;
dm_ado->gr_update_exams_sp->Prepared = true;
dm_ado->gr_update_exams_sp->ExecProc();
(в данный момент помидоры летящие из зала в убогую процедуру прошу не кидать)
прошло. данные обновились. перед занавесом делаю
void __fastcall Tfrm_main_gr::MemTableEh1AfterPost(TDataSet *DataSet)
{
AnsiString val = DBGridEh2->SelectedField->Value;
if (Trim(val) == "5") val = "îòë";
if (Trim(val) == "4") val = "õîð";
DBGridEh2->SelectedField->Value = val;
}
в надежде перевести данные из цифровой формы в символьную но тщетно — на сетке только то что ввел пользователь.
сцена 3: пользователь нажал кнопку добавить поле и ввелд данные.
у меня повешен след код
dm_ado->add_subj->Close();
AnsiString sql_text = "insert into exams (date_exam, id_p , id_sub) values ('"+ DateTimePicker1->Date +"','" + dm_ado->sel_id_pup_from_group->FieldByName("id_p")->Value + "','"+ dm_ado->sel_id_subj->FieldByName("id_sub")->Value+ "')";
dm_ado->add_subj->SQL->Text = sql_text;
dm_ado->add_subj->Prepared = true;
dm_ado->add_subj->ExecSQL();
изменения отразились в базе!!! но не в сетке. если сделать переключение с форму куда-либо а потом обратно, то тогда он отобразится на форме.
как сделать так чтобы он отображался сразу и в ячейках таблицу отображалась актуальная инфа — непонятно. все занавес. полетели помидоры...
|
|
olegenty |
Отправлено: 12.08.2005, 11:12 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
ну, мил человек, теперь объясни мне на пальцах, зачем тебе при таком подходе MemTableEh, если ты всё делаешь по-старинке. столько кода вместо того, чтобы (ВСЕГО ЛИШЬ) заполнить соответствующие св-ва компонента TADODataDriverEh. ты ж фичами-то и не пользуешься.
резюме — переделай. св-ва заполни просто. ты удивишься, но это работатет лучше. там же параметры есть. приврати всё в параметрические запросы. оперируй ТОЛЬКО св-вами TADODataDriverEh. и никаких ещё дополнительных компонентов, кроме TADODataDriver и TMemTableEh не используй при этом. для одного набора данных по одной штуке. если селекты генерит пользователь — наздоровье, тогда перегенеривай и св-ва TADODataDriver. и будет тебе аналог счастья в цвете.
|
|
greyich |
Отправлено: 12.08.2005, 12:03 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 45
|
QUOTE (olegenty @ 12/08/2005, 11:12) | ну, мил человек, теперь объясни мне на пальцах, зачем тебе при таком подходе MemTableEh, если ты всё делаешь по-старинке. столько кода вместо того, чтобы (ВСЕГО ЛИШЬ) заполнить соответствующие св-ва компонента TADODataDriverEh. ты ж фичами-то и не пользуешься.
резюме — переделай. св-ва заполни просто. ты удивишься, но это работатет лучше. там же параметры есть. приврати всё в параметрические запросы. оперируй ТОЛЬКО св-вами TADODataDriverEh. и никаких ещё дополнительных компонентов, кроме TADODataDriver и TMemTableEh не используй при этом. для одного набора данных по одной штуке. если селекты генерит пользователь — наздоровье, тогда перегенеривай и св-ва TADODataDriver. и будет тебе аналог счастья в цвете. |
так. почему я перешел на memtableeh и datadrivereh (кстати может пора уже както назвать эту технологию или узнать у разработчика как она называется) было обсуждено выше.
ничего кроме этого я и не использую (разве что datasource — но куда без него?)
подскажите мне как найти информацию по параметрическим запросам. в билдеровском хелпере описывалось через заполнение вручную (как я и сделал) и поиск по форумам не дал ничего вразумительного.
и зачем перегенерировать свойства tadodatadriver?
|
|
olegenty |
Отправлено: 12.08.2005, 12:19 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
перегенерировать св-ва TADODataDriver нужно только в том случае, если SelectSQL формируется пользователем, при этом меняется количество параметров, либо количество параметров неизменно, но изменилось количество полей ОДНОЙ таблицы, которую при этом хочется одновлять. во всех остальных случаях (т.е. количество параметров SelectSQL одно и то же и количество полей — величина постоянная), никакие компоненты, кроме ОДНОГО TADODataDriver и ОДНОГО TMemTableEh — не нужны. эта пара приспокойно справится с любой работой.
SQL | create table dbo.test (
id int primary key
, name varchar (50)
|
SelectCommand
CommandText
SQL | select id, name from dbo.test where name like :NameParam
|
Parameters — 1 штука:
Name = NameParam
DataType = ftString
Derection = pdInput
Size = 50
UpdateCommand
CommandText
SQL | update dbo.test set name = :name where id = :id
|
Parameters — 2 штуки. их НЕОБХОДИМО ОПИСАТЬ, но не надо заполянть вручную. в случае. когда имя параметра совпадает с именем поля, его значение и берётся из поля.
Item 0 (параметр 1)
Name = id
DataType = ftInteger
Derection = pdInput
Item 1 (параметр 2)
Name = name
DataType = ftString
Derection = pdInput
Size = 50
и ВСЁ!!! никаких ручных заполнений св-в в рантайме!!! TADODataDriver сам всё сделает. И только когда его стандартное поведение чем-то не устраивает, надо писать обработчики событий. Например, если делаешь вставку, а в таблице есть поле identity, то тогда вставку надо делать уже с помощью хранимой процедуры, которая будет возвращать значение этого поля, а ты РУКАМИ подсунешь его в MemoryTable в обработчике OnGetBackUpdatedValues. И это, пожалуй, единственное, что там надо делать руками.
|
|
olegenty |
Отправлено: 12.08.2005, 12:22 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
да и то, не отдельным компонентом, а всё тем же TADODataDriver — после выполнения хранимки он корректно вернёт прямо в обработчик выходные параметры.
|
|
greyich |
Отправлено: 12.08.2005, 13:27 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 45
|
ладно. буду учится. создам новый проект и попробую нарисовать. кстати www.nigma.ru на запрос о параметризованных запросах отсылает на этот форум к постам olegenty и avc
|
|
olegenty |
Отправлено: 12.08.2005, 13:35 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
Ну нету у меня времени на статью, честно. На работе — работа. Дома — жена и сын (такую, чтоб с картинками)
кстати, а примеры тебе чем не глянулись, те, что в MTDEMOS?
|
|
greyich |
Отправлено: 15.08.2005, 16:18 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 45
|
хотя наверно вопрос не сюда, но все-таки попробую продолжить ветку...
к вопросу о параметрическим запросах
я конечно опять всё не так делаю, но если я сам хочу заполнить параметры command в рантайме? скажем часть не совпадает с полями,а часть нужно вручную подготовить
|
|
olegenty |
Отправлено: 16.08.2005, 06:55 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
тогда
1. Да, создаёшь параметры руками
2. Заволняешь несовпадающие параметры либо
2.1 Перед открытием запроса
либо
2.2 в событии OnAssignComandParameter
в случае 2.2 надо быть внимательным: когда есть обработчик этого события, все заполнения параметров по умолчанию уже не работают, поэтому для несовпадающих с именами полей параметров надо заполнять их вручную, а для совпадвющих вызывать DefaultAssignComandParameter
|
|
olegenty |
Отправлено: 23.08.2005, 08:34 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
для тех, кто работает с MemTableEh + ADODataDriverEh
при вынесении в отдельный поток метода Open() компонента MemTableEh на длинных выборках ГАРАНТИРОВАННО наступает Command Timeout через 30 секунд.
править так:
CODE |
case Command.CommandType of
cthSelectQuery, cthUpdateQuery:
begin
ACursor := TADOQuery.Create(nil);
with ACursor as TADOQuery do
begin
Connection := ADOConnection;
ConnectionString := ConnectionString;
////////////////////////////
if Assigned(Connection) then CommandTimeout :=Connection.CommandTimeout;
|
т.е. надо ручками выставить CommandTimeout.
Большакову уже сказал, думаю, исправит.
|
|
greyich |
Отправлено: 23.08.2005, 12:45 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 45
|
QUOTE (olegenty @ 23/08/2005, 08:34) | для тех, кто работает с MemTableEh + ADODataDriverEh
при вынесении в отдельный поток метода Open() компонента MemTableEh на длинных выборках ГАРАНТИРОВАННО наступает Command Timeout через 30 секунд.
править так:
CODE |
case Command.CommandType of
cthSelectQuery, cthUpdateQuery:
begin
ACursor := TADOQuery.Create(nil);
with ACursor as TADOQuery do
begin
Connection := ADOConnection;
ConnectionString := ConnectionString;
////////////////////////////
if Assigned(Connection) then CommandTimeout :=Connection.CommandTimeout;
|
т.е. надо ручками выставить CommandTimeout.
Большакову уже сказал, думаю, исправит. |
то есть полминуты посчитывали данные а потом — фигушки вам больше и не надо
|
|
spiller |
Отправлено: 26.06.2006, 21:14 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 27
|
Гуру, подскажите.
Я пока изучал help по Ehlib английский язык выучил, понимания технологии так и не добился... (
Скажите а как узнать значение GridEh под мышкой?
B как обстоят дела со множественным выделением?
Отредактировано spiller — 26/06/2006, 21:18 |
|
olegenty |
Отправлено: 27.06.2006, 06:37 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
множественное выделение есть в примере. (TDBGridEh.Selection)
|
|
Gedeon |
Отправлено: 27.06.2006, 12:57 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
QUOTE (spiller @ 26/06/2006, 21:14) | Скажите а как узнать значение GridEh под мышкой?
|
Ищите на форуме есть ветка GridUnderMouse AVC выложил очень хороший работающий пример.
|
|
Gedeon |
Отправлено: 27.06.2006, 13:00 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
вот нашел, юзайте
gum
|
|
spiller |
Отправлено: 08.07.2006, 21:30 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 27
|
Спасибо. Изучил.
Еще вопросик, скажите мне пожалуйста, в чем суть свойства GetRecCommand компонента TADODataDriver? Я что-то читал, что запрос на изменение данных на клиенте, но, скажите пожалуйста, зачем тогда UpdateCommand?
И еще, есть ли метод, который перезапрашивает данные с сервера?
Пока делаю так:
CODE |
MemTable->Close();
MemTable->Open();
|
Cпасибо!
Отредактировано spiller — 08/07/2006, 21:30 |
|
olegenty |
Отправлено: 09.07.2006, 06:14 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
перезапрашиваются данные именно так, как ты это делаешь, если речь идёт о ВСЕЙ ВЫБОРКЕ.
в свою очередь, GetRecCommand перезапрашивает даннык об одной ТЕКУЩЕЙ (ВЫБРАННОЙ) записи, посредством вызова метода RefreshRecord
|
|
Guest |
Отправлено: 09.07.2006, 09:59 |
|
Не зарегистрирован
|
МММ, понятно!
Можно еще вопрос?)
ADO-MySQL
Допустим у меня таблица типа словарь:
ID- типа autoIncrement
Name — varchar(200)
Вот. Есть у меня вся связка для работы с "живым" набором данных:
ADoDataDriverEh — MEmTableEh — DataSourseEh — GridEh
Вот. Свойство SelectSQL просто выбирает все Name и отображает в гриде.
Но мне очень желательно, чтобы в гриде был еще один столбец- просто числа от 1 до числа всех этих Name. Как мне их правильно проставить?
Спасибо заранее!
Прошу прощение за нескромность;) |
|
olegenty |
Отправлено: 09.07.2006, 12:51 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
в смысле, не ID из базы, а просто локально от 1 и до последней записи? просто создаёшь Calculated поле, например RecNo, и в OnCalcFields пишешь:
CODE |
YourMemTableRecNo->AsInteger = YourMemTable->RecNo;
|
для корректной работы сей штуки надо выставлять FetchAllOnOpen в true. (а может и не надо — не помню)
|
|
spiller |
Отправлено: 09.07.2006, 19:06 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 27
|
благодарче, все получилось
Отредактировано spiller — 10/07/2006, 19:20 |
|
spiller |
Отправлено: 10.07.2006, 19:21 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 27
|
Добрый день всем обитателям этого форума!
Попробую и я задать вопросик к знатокам
У господина большакова в примерах нашел процедуру "живого удаления записей":
Код:
CODE |
procedure TForm1.ppmDeleteClick(Sender: TObject);
begin
if (ActiveControl is TDBGridEh) then
with TDBGridEh(ActiveControl) do
if CheckDeleteAction and (geaDeleteEh in EditActions) then
DBGridEh_DoDeleteAction(TDBGridEh(ActiveControl),False);
end;
|
Привильно ли я понял, что можно проссто выделить определенные ячейки и они удалятся в самой БД, если все это хозяйство висит на TXXXDataDrivere c прописанным DeleteSQL?
Ие еще не получается у применить DBGridEh_DoDeleteAction . РУгается что это не член класса. Я тоже такого метода не припомню. Найти в других файлах так и не удалось[CODE]
Отредактировано spiller — 10/07/2006, 19:21 |
|