C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

стр.: (4) < 1 [2] 3 4 >
как оседлать DBGridEh? (sql server+ado+dbgrideh), редактирование записей в гриде вручную
greyich
Отправлено: 06.08.2005, 16:23


Дежурный стрелочник

Группа: Участник
Сообщений: 45



а почему метод RefreshRecord вызывает ошибку? данные менять можно а вот отобразить их сразу же не получается

Отредактировано greyich — 06/08/2005, 16:40
olegenty
Отправлено: 08.08.2005, 06:58


Ветеран

Группа: Модератор
Сообщений: 2412



ты св-во GetRecCommand заполнил? А какая ошибка-то, огласи уж...
greyich
Отправлено: 08.08.2005, 12:29


Дежурный стрелочник

Группа: Участник
Сообщений: 45



QUOTE (olegenty @ 08/08/2005, 06:58)
ты св-во GetRecCommand заполнил? А какая ошибка-то, огласи уж...



нет. а надо было? biggrin.gif


ошибка  — обычный exeption, по поводу того что память не может быть read. иногда ругался на отсутствие sql выражения в DataDriverEh (но где конкретно не указывал).

хелп

TSQLDataDriverEh содержит четыре(!!!!) объекта типа TSQLCommandEh: SelectCommand, DeleteCommand, InsertCommand, UpdateCommand, GetrecCommand которые хранят SQL выражения и параметры соответственно для запроса данных, удаления записи, вставки записи, изменения записи, перезапроса записи.

не догнал — чем отличается перезапрос (во придумали то!) от запроса на чтение данных — мне казалось что заполнение селекта достаточно. если нет то чем заполнять getreccommand? тем же самым?
olegenty
Отправлено: 08.08.2005, 13:59


Ветеран

Группа: Модератор
Сообщений: 2412



нет, не тем же самым, а запросом на обновление ОДНОЙ записи. только той, что ТЕКУЩАЯ. (аднака, билин, глючит метод RefreshRecord, о чём я уже отписал Дмитрию Большакову.)
greyich
Отправлено: 08.08.2005, 14:20


Дежурный стрелочник

Группа: Участник
Сообщений: 45



QUOTE (olegenty @ 08/08/2005, 13:59)
нет, не тем же самым, а запросом на обновление ОДНОЙ записи. только той, что ТЕКУЩАЯ. (аднака, билин, глючит метод RefreshRecord, о чём я уже отписал Дмитрию Большакову.)

так он вызывается сразу после событий updaterecord, insert и delete?

и какой-таки глюк?

MemTableEh1->Active = false;
MemTableEh1->Active = true;
вызывает "access violation in address bla-bla-bla"


просто у меня в dbgrid выводятся результаты запроса который формируется на серваке. хотелось бы чтобы пользователь ввел одно и после updaterecord получил другое в сетке.

Отредактировано greyich — 08/08/2005, 14:20
olegenty
Отправлено: 09.08.2005, 05:33


Ветеран

Группа: Модератор
Сообщений: 2412



компонент сыроват. ты что-то сделал неверно — получил ошибку. он хорошо работает только когда всё делаешь правильно.
olegenty
Отправлено: 09.08.2005, 06:36


Ветеран

Группа: Модератор
Сообщений: 2412



о! я GetRecCommand поборол. для MSSQL корректно работает только в случае cthSelectQuery, при этом в селекте exec dbo.uspsr_.... наблюдение:
1. cthSelectQuery + select = AV
2. cthStoredProc = AV
другие типы команд тут не подходят.
поковырялся в отладчике. почему ХП не работает — понятно. в том куске кода она словно имеет пустыми/нереальными св-ва предочного TDataSet. похоже отрабатывает, как ХП, не возвращающая записей. ну и хрен бы с ней.

резюме: всё работает.
greyich
Отправлено: 09.08.2005, 13:30


Дежурный стрелочник

Группа: Участник
Сообщений: 45



QUOTE (olegenty @ 09/08/2005, 06:36)
этом в селекте exec dbo.uspsr_.... наблюдение:
1. cthSelectQuery + select = AV
2. cthStoredProc = AV
другие типы команд тут не подходят.

ничего не понял. хранимки не проходят?
olegenty
Отправлено: 09.08.2005, 13:49


Ветеран

Группа: Модератор
Сообщений: 2412



проходят, но в описанном выше варианте. при этом, в InsertCommand, UpdateCommand, DeleteCommand — проходят на ура, со свистом.
greyich
Отправлено: 09.08.2005, 16:53


Дежурный стрелочник

Группа: Участник
Сообщений: 45



QUOTE (olegenty @ 09/08/2005, 05:33)
компонент сыроват. ты что-то сделал неверно — получил ошибку. он хорошо работает только когда всё делаешь правильно.

а что значит правильно в этом случае?
olegenty
Отправлено: 10.08.2005, 07:43


Ветеран

Группа: Модератор
Сообщений: 2412



правильно, это значит так, чтобы без потери функционала всё работало. наиболее правильно, почему-то, работает завязка на ХП. я не стал разбираться, почему, — достаточно было определиться с этим импирически. теперь select, update, delete, insert, getrec — заваязаны на ХП, и работа меня более, чем устраивает. Большаков ведь и сам писал, что TMemTableEh — пока только задумка. Тест. Возможны любые изменения, исправления, вплоть вообще до закрытия этой ветки библиотеки. Однако, в EhLib 4 MemTable войдёт уже как полноценная часть библиотеки. Опять же, жалуетесь на глюки? А сколько дензнаков вы заплатили разработчику, чтобы их не было?
greyich
Отправлено: 10.08.2005, 08:37


Дежурный стрелочник

Группа: Участник
Сообщений: 45



да нет, на глюки не жалуюсь, потому как я действительно и не платил ничего. но во-первых: как говорил сам автор — для Росии эта программа бесплатна, так как росиийские многие разработчики помогают в отлавливании глюков и всё такое, в во-вторых я даже готов заплатить 50$ за такое чудо и за жизнь без глюков smile.gif
зы: а когда выйдет ehlib 4?
olegenty
Отправлено: 10.08.2005, 08:42


Ветеран

Группа: Модератор
Сообщений: 2412



не знаю. ссылку на "пред-альфа" 4 версию он мне дал недели полторы назад. вот и думай. может к зиме. не думаю, что ранше. хотя, можно и спросить.
касаемо же платности... имел я с ним диалог на эту тему... так вот, наши халявщики не столько помогают в beta-тестировании, сколько засыпают глупыми вопросами, не разобравшись в предмете. это скорее раздражает, чем приводит к какому-то ещё эффекту, сам понимаешь.
greyich
Отправлено: 10.08.2005, 09:27


Дежурный стрелочник

Группа: Участник
Сообщений: 45



но тем не менее для росии она бесплатная. были же какие-то мотивы так поступить
olegenty
Отправлено: 10.08.2005, 09:57


Ветеран

Группа: Модератор
Сообщений: 2412



есс-но были. я не спрашивал, какие. но теперь появляются мотивы сделать пакет платным. и в перспективе это вполне возможно. я тоже отдаю себе отчёт, что в этом случае пакет придётся покупать на свои, но это как раз тот пакет, который я-таки куплю, когда он станет платным.
greyich
Отправлено: 10.08.2005, 12:31


Дежурный стрелочник

Группа: Участник
Сообщений: 45



все-таки я не понимаю как прописать GetRecCommand. можно пример кода в студию?

"select field1, field2, field3 from table1 where key = ' " +DBGridEh1->SelectField->Value+ " ' "

так? и если я скажем хочу добавить столбец, то как мне это поможет?
olegenty
Отправлено: 10.08.2005, 12:44


Ветеран

Группа: Модератор
Сообщений: 2412



ну ты перец. вот мой вариант GetrecSQL:
SQL
exec dbo.uspsr_Route :InstanceID

где dbo.uspsr_Route — хранимая процедура, возвращающая поля ОДНОЙ записи, а InstanceID — ключевое поле

примечание 1: набор полей, их тип и порядок следования в запросе должны быть идентичны аналогичным из SelectSQL

примечание 2: InstanceID — в моём случае имя поля текущей записи, которое, соответственно, автоматически используется, как параметр. если же это не так, то надо писать обработчик события OnAssignCommandParameter, где анализировать, что за команда выполняется и какой параметр запрашивается. если интересующий — то заполнить его в обработчике, иначе — вызвать обработчик по умолчанию.
greyich
Отправлено: 10.08.2005, 13:15


Дежурный стрелочник

Группа: Участник
Сообщений: 45



ìíå ñëîæíåå ÷òîòî ïðèäóìàòü ïîòîìó ÷òî âîò ê ïðèìåðó òî ÷òî ÿ çàñîâûâàþ â datadriver

CODE

dm_ado->gr_exams->Active = false;
AnsiString sql_text = "select distinct(pupil_fio), id_p ";
AnsiString title_temp = "";
dm_ado->sel_subjects->First();
for (int i=1;i<=dm_ado->sel_subjects->RecordCount; i++)
{
 if (!dm_ado->sel_subjects->FieldByName("title")->IsNull)
 title_temp = dm_ado->sel_subjects->FieldByName("title")->Value;
 sql_text = sql_text + ",(select full_mark from vwgrexams vw where  vw.pupil_fio = vwgrexams.pupil_fio and vw.title = ";
 sql_text = sql_text +"'" +title_temp+ "') as '"+  title_temp+ "' ";
 dm_ado->sel_subjects->Next();
}
sql_text = sql_text + " from vwgrexams order by pupil_fio";

ADODataDriverEh1->SelectCommand->CommandText->Text =  sql_text;
 MemTableEh1->Active = true;


ê ñîæàëåíèþ õðàíèìêè íå õî÷åòñÿ èñïîëüçîâàòü òàê êàê òàì ñ öèêëàìè íàãåìîððîþñü. à êîä êîòîðûé òû ïðèâåë (è â ïåðâîì è âî âòîðîì ñëó÷àå ) íå ïîíèìàþ.

âîîáùåì òû âûçûâàåøü õðàíèìóþ ïðîöåäóðó è ïåðåäàåøü åé çíà÷åíèå êëþ÷åâîãî ïîëÿ, ïðàâèëüíî? à õðàíèìàþ ñîîòâåòñòâåííî âîçâðàùàåò âñå ïîëÿ çàïèñè êîòîðàÿ îòíîñèòñÿ ê êëþ÷åâîìó ïîëþ. õîðîøî à êàê òàêè áûòü ñ äîáàâëÿåìûìè ñòîëáöàìè?
greyich
Отправлено: 10.08.2005, 13:16


Дежурный стрелочник

Группа: Участник
Сообщений: 45



мне сложнее чтото придумать потому что вот к примеру то что я засовываю в datadriver

CODE

dm_ado->gr_exams->Active = false;
AnsiString sql_text = "select distinct(pupil_fio), id_p ";
AnsiString title_temp = "";
dm_ado->sel_subjects->First();
for (int i=1;i<=dm_ado->sel_subjects->RecordCount; i++)
{
 if (!dm_ado->sel_subjects->FieldByName("title")->IsNull)
 title_temp = dm_ado->sel_subjects->FieldByName("title")->Value;
 sql_text = sql_text + ",(select full_mark from vwgrexams vw where  vw.pupil_fio = vwgrexams.pupil_fio and vw.title = ";
 sql_text = sql_text +"'" +title_temp+ "') as '"+  title_temp+ "' ";
 dm_ado->sel_subjects->Next();
}
sql_text = sql_text + " from vwgrexams order by pupil_fio";

ADODataDriverEh1->SelectCommand->CommandText->Text =  sql_text;
 MemTableEh1->Active = true;


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

вообщем ты вызываешь хранимую процедуру и передаешь ей значение ключевого поля, правильно? а хранимаю соответственно возвращает все поля записи которая относится к ключевому полю. хорошо а как таки быть с добавляемыми столбцами?
olegenty
Отправлено: 10.08.2005, 13:47


Ветеран

Группа: Модератор
Сообщений: 2412



... да УЖ. ты б для начала формализовал слегонца работу-то с собственными данными. то, что ты тут нарисовал — это неживой вариант. мёртворожденный код, да и только.

теперь о пользе хранимых процедур: хранимая процедура СКРЫВАЕТ от клиентского приложения тонкости внутренней реализации. переделал я что-то в середине БД, изменил хранимки, и ПРИЛОЖЕНИЕ РАБОТАЕТ И ДАЛЬШЕ, а что надо сделать тебе? ПЕРЕПИСАТЬ код приложения в части формирования запросов. я бы такую курсовую не принял, не то, что готовую программу. кстати, вот сейчас, разбиваю одну таблицу на 2. очень удобно: клиентская часть не пострадает smile.gif.
greyich
Отправлено: 10.08.2005, 15:48


Дежурный стрелочник

Группа: Участник
Сообщений: 45



QUOTE (olegenty @ 10/08/2005, 13:47)
... да УЖ. ты б для начала формализовал слегонца работу-то с собственными данными. то, что ты тут нарисовал — это неживой вариант. мёртворожденный код, да и только.

теперь о пользе хранимых процедур: хранимая процедура СКРЫВАЕТ от клиентского приложения тонкости внутренней реализации. переделал я что-то в середине БД, изменил хранимки, и ПРИЛОЖЕНИЕ РАБОТАЕТ И ДАЛЬШЕ, а что надо сделать тебе? ПЕРЕПИСАТЬ код приложения в части формирования запросов. я бы такую курсовую не принял, не то, что готовую программу. кстати, вот сейчас, разбиваю одну таблицу на 2. очень удобно: клиентская часть не пострадает smile.gif.

да я понимаю чем хранимки лучше! я же говорю реализовать этот код на sql я не смог — пришлось формировать динамически на клиенте. мне нравится как реализована моя БД и вроде как не собираюсь менять структуру данных.
olegenty
Отправлено: 11.08.2005, 06:41


Ветеран

Группа: Модератор
Сообщений: 2412



ну давай так. таблица (THIS_TABLE):
ID int identity prinary key
, NAME varchar(100)
, DESCRIPTION varchar(2000)

1. SelectSQL
SQL
select
ID
, NAME
, DESCRIPTION
from THIS_TABLE where NAME like :Condition

2. GetrecSQL
SQL
select
ID
, NAME
, DESCRIPTION
from THIS_TABLE where ID = :ID


вот и всего-то делов
greyich
Отправлено: 11.08.2005, 12:31


Дежурный стрелочник

Группа: Участник
Сообщений: 45



ну я выше так и написал!!!!! smile.gif)
странно но не работает почемуто

CODE


ADODataDriverEh1->SelectCommand->CommandText->Text = sql_text;
MemTableEh1->Active = true;
ADODataDriverEh1->GetrecCommand->CommandText->Text = sql_text + " where id_p = '" + MemTableEh1->FieldByName("id_p")->Value + "'";



вот такой код — на getreccomman повешен тот же sql лишь с заданием ключевого поля. у меня в сетку вводится число а в таблице хранится слово (пример "5" и "пять") и на экране отображается только число sad.gif

если смотреть внимательно твои посты то в одном месте ты говоришь о getreccommand а в другом о getrecsql а в чем вообще разница? (чтото у меня браузер глючит)
olegenty
Отправлено: 11.08.2005, 12:39


Ветеран

Группа: Модератор
Сообщений: 2412



присмотрись к компоненту:
свойство GetrecSQL — это всего лишь ссылка на GetrecCommand->CommandText, просто GetrecComand содержит ещё и коллекцию параметров, тип команды и т.д.
greyich
Отправлено: 11.08.2005, 18:43


Дежурный стрелочник

Группа: Участник
Сообщений: 45



понял. кстати ничего так ветка получилась smile.gif можно рекомендовать как faq для новичков
olegenty
Отправлено: 12.08.2005, 06:59


Ветеран

Группа: Модератор
Сообщений: 2412



у тебя-то заработало?
AVC
Отправлено: 12.08.2005, 08:04


Ветеран

Группа: Модератор
Сообщений: 1583



QUOTE (greyich @ 11/08/2005, 11:31)

CODE

ADODataDriverEh1->SelectCommand->CommandText->Text = sql_text;
MemTableEh1->Active = true;
ADODataDriverEh1->GetrecCommand->CommandText->Text = sql_text + " where id_p = '" + MemTableEh1->FieldByName("id_p")->Value + "'";


Пару замечаний позволите?
1. Заменить FieldByName("id_p")->Value на FieldByName("id_p")->AsString
2. Вообще заменить этот кусок на использование параметра :id_ip. Если я правильно понял, то в случае когда имя параметра совпадает с именем поля, значение будет подставлено автоматически (обычная практика).
3. sql_text + " where " — плохая практика, так как очень часто sql_text закнчивается Order by (это не считая Having, Group, Union ...). Если сервер позволяет (а MSSql, таки да, позволяет) можно
а) Обернуть sql_text в еще один Select
б) Выполнить макроподстановку внутри sql_text (предпочтительный вариант)
+ не забудьте, что после RefreshRecord запись может выйти из зоны видимости.

PS.
В вашем примере, в зависимости от места расположения кода, вы можете всегда обновлять только первую запись.
greyich
Отправлено: 12.08.2005, 08:23


Дежурный стрелочник

Группа: Участник
Сообщений: 45



QUOTE (olegenty @ 12/08/2005, 06:59)
у тебя-то заработало?

неа. и что самое странное столбец проявляется в сетке только когда я закрываю/открываю форму (то есть он совершенно правильно добавляется в набор данных)
код
CODE

MemTableEh1->Active = false;
MemTableEh1->Active = true;

как впрочем
CODE

DBGridEh2->Enabled = false;
DBGridEh2->Enabled = true;

не помогают. и самое обидное что пользователь видя такие вещи считает их глюком (в какойто мере он прав). буду биться sad.gif
greyich
Отправлено: 12.08.2005, 08:35


Дежурный стрелочник

Группа: Участник
Сообщений: 45



QUOTE (AVC @ 12/08/2005, 08:04)
Пару замечаний позволите?
1. Заменить FieldByName("id_p")->Value на FieldByName("id_p")->AsString
2. Вообще заменить этот кусок на использование параметра :id_ip. Если я правильно понял, то в случае когда имя параметра совпадает с именем поля, значение будет подставлено автоматически (обычная практика).
3. sql_text + " where " — плохая практика, так как очень часто sql_text закнчивается Order by (это не считая Having, Group, Union ...). Если сервер позволяет (а MSSql, таки да, позволяет) можно
а) Обернуть sql_text в еще один Select
б) Выполнить макроподстановку внутри sql_text (предпочтительный вариант)
+ не забудьте, что после RefreshRecord запись может выйти из зоны видимости.

PS.
В вашем примере, в зависимости от места расположения кода, вы можете всегда обновлять только первую запись.

замечания приму с удовольствием (я еще новичок в билдере — около полугода)

1. а еще лучше на FindField
а) несколько не понял что значит "обернуть sql_text в еще один select". не могли бы вы пояснить подробнее
б) другими словами adoquery не рулит и рекомендуется пользоваться хранимыми?

кстати текст записанный в
ADODataDriverEh1->GetrecCommand->CommandText->Text сработал только после вызова RefreshRecord. на все остальные попытки, как например закрыти и открытие набора данных и сетки, он молчал в тряпочку.
olegenty
Отправлено: 12.08.2005, 08:36


Ветеран

Группа: Модератор
Сообщений: 2412



возможно, тебе поможет какая-то из этих строк (или их комбинация):
CODE

MemTable->FieldDefs->Update();
MemTable->FieldDefList->Update();
MemTable->FieldList->Update();


Persistent полей, я надеюсь, у тебя там нет?
стр.: (4) < 1 [2] 3 4 >
Вернуться в Работа с базами данных в C++Builder