Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
08-11-2006 15:06 | Комментарий к предыдущим ответам
Эх... Куда катимся!!! Раньше написать программу под 16Кб - это просто было расточительно... А сейчас? А сейчас с гигабайтами оперативки все пишут как вздумается... А потом производителям ПК говорим, что их мащностей маловато... Надо ещё пол терабайта оперативки, процессор P-V 5000 GHz и т.п. Сразу скажу: не уважаю тех, кто делает тяп-ляп... Восхищаюсь интузазистами, которые в 64 Кб 3D приложение умещают! Асм великое дело! Ладно... Видать я старею... Не буду бурчать...
P.S. Кстати... Много катался по командировкам по "окраинам" России. И там многие ещё используют такие компы, как я указал. А у меня конечно старенький, но P-IV 2400MHz с гигом оперативки...
Да потому что нет BeginUpdate/EndUpdate! А это приводит к тому, что несколько операторов SQL.Add заставляют компонент парсить запрос на наличие параметров, которых может и не быть! А это, хоть и маленькое, но время процессора! И это только на маленьких запросах... :)))
To Banderas:
Хоть один человек понимает о чём я толькую... ;)))
Не хорошо как-то получается... Из твоих обяснений в данном топике можно сделать вывод, что SQL.Text и несколько SQL.Add выполняют одно и тоже... Ты привёл здесь кусок кода из TADOQuery, но... Почему же ты убрал BeginUpdate/EndUpdate из кода? SQL.Add в SQL.Text совсем не так работает, как простой SQL.Add и ты это знаешь, славный рыцарь... Потому что без BeginUpdate/EndUpdate при каждом SQL.Add запросы снова парсятся!
// Этот вариант
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select * from employees');
ADOQuery1.SQL.Add('where empid = :empid');
// Не равен этому
ADOQuery1.SQL.Text := 'select * from employees where empid = :empid';
03-11-2006 01:02 | Комментарий к предыдущим ответам
Коллеги, о чем мы спорим? Я не призываю всех перейти на Add. В каком-то случае лучше хранить запросы в ресурсах, в каком-то создавать хранимые процедуры. А в случае построения сложного динамического запроса можно и Add воспользоваться. Мир многогранен!
Ты можешь смеяться, но... У меня есть запрос, который весит 131Кб... А теперь представь себе: сколько же надо вставить SQL.Add на такой запрос? Или как он будет читаться в присваении SQL.Text? Кроме того, у использования данных функций есть свой плюс: запросы можно редактировать без наличия исходников любым редактором ресурсов...
To voldan:
Нет, это не "мотоцикл", это оптимизация кода... Поверь мне... Я видел модули, которые весят по пол метра (более 100 000 строк), и, в большинстве своём, именно SQL.Add там и использовали... Как ты думаешь, другому программисту, который прийдёт на работу, будет хорошо ковыряться в таком коде? И ещё без форматирования... Хотя тебе видней...
31-10-2006 13:40 | Комментарий к предыдущим ответам
2 Куфенко Павел:
А что... Если длиные, то низя?!?! Вот тебе раз... Ну тогда держи немного кода, пока я здоров и в своём уме... ;)
Что-то ты слишком сложно завернул :) Проще было:
ADOQuery1.SQL.Text := '-- Здесь пятьдесят строк комментария запроса ;)'
+ '-- ...'
+ '-- ...'
+ '-- Все пятьдесят мне писать в ломы... ;)'
+ 'SELECT * FROM Employees';
А если серьезно, откуда такая неприязнь к SQL.Add? Если, например, нужно обрабатывать какие-либо данные и делать вставку в БД динамическим запросом, более удобную альтернативу вряд ли найти.
31-10-2006 12:15 | Комментарий к предыдущим ответам
To Green:
А что... Если длиные, то низя?!?! Вот тебе раз... Ну тогда держи немного кода, пока я здоров и в своём уме... ;)
function LoadSQL(const ResourceID: Cardinal): string; overload;
begin
with TResourceStream.CreateFromID(hInstance, ResourceID, RT_RCDATA) do
try
SetLength(Result, Size);
if Size > 0 then ReadBuffer(Result[1], Size);
finally
Free;
end;
end;
function LoadSQL(const ResourceID: Cardinal; const Arguments: array of const): string; overload;
begin
Result := Format(LoadSQL(ResourceID), Arguments);
end;
Вот так выглядит большой запрос:
-- Здесь пяьтдесят строк комментария запроса ;)
-- ...
-- ...
-- Все пятьдесят мне писать в ломы... ;)
Да сидят там в Борланде ламеры, делать нечего им, и вместо того, чтоб дыры залатывать - они то выставляют обработчики, то сбрасывают, то выставляют, то сбрасывают... :)
)))))))) Ребята, не ссорьтесь!!! Смешно на вас смотреть! Я вопрос задавал совсем про другое, но раз уж тут спор вышел, вставлю свои пять копеек и скажу, что как я понял, в Дельфи 7 запрос закрывается автоматически при изменении SQL, а в Д5 (как у меня) нет. Просто я уже с одним товарищем в аське этот вопрос обсуждал, и он с пеной у рта мне доказывал, что запрос закрывается сам, а у меня-то не закрывается :-)) Сравнили потом версии дельфи и пришли к консенсусу )))
Ай-яй-яй, Green :)
Вы же славный Великий рыцарь! :)))
"Долой Green'а!" - кричала толпа. "Он недостоин почетного звания рыцаря!"
Из последних сил трясущимися руками Green набрал на клавиатуре следующий код:
procedure TForm1.Button1Click(Sender: TObject);
begin
ADOQuery1.SQL.Text := 'select * from sectors';
ADOQuery1.Open;
if ADOQuery1.Active then ShowMessage('Active') else ShowMessage('Not active');
ADOQuery1.SQL.Text := 'select * from sectors';
if ADOQuery1.Active then ShowMessage('Active') else ShowMessage('Not active');
end;
О, чудо! При изменении текста запроса запрос закрылся автоматически! Green спасен! :)
В чем же секрет? Обратимся к исходникам. При создании компонента TADOQuery к его свойству SQL цепляется обработчик, реагирующий на изменение текста запроса:
constructor TADOQuery.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FSQL := TStringList.Create;
TStringList(FSQL).OnChange := QueryChanged; // Вот тут!
Command.CommandTextAlias := 'SQL'; { Do not localize }
end;
Этот обработчик при изменении текста запроса закрывает его:
procedure TADOQuery.QueryChanged(Sender: TObject);
begin
if not (csLoading in ComponentState) then
Close; // Вот тут!
CommandText := FSQL.Text;
end;
Green, я цитирую Вас:
Даже если компонент ранее содержал запрос, возвращающий данные и был открыт, то при изменении текста запроса он все равно закроется автоматически
Это Ваши слова.
то есть, это значит:
Query.Close;
Query.SQL.Text := 'Select * from T';
Query.Open;
и вот тут.. :)
Query.SQL.Text := 'Select * from B'
вы утверждаете, что он все равно закроется автоматически
Ай-яй-яй, Green :)
Вы же славный Великий рыцарь! :)))
а зачем использовать ADOQuery1.Active := false при ADOQuery1.ExecSQL?
В принципе это не нужно. Даже если компонент ранее содержал запрос, возвращающий данные и был открыт, то при изменении текста запроса он все равно закроется автоматически. Я так делаю скорее по привычке.
а зачем использовать ADOQuery1.Active := false при ADOQuery1.ExecSQL?
если ADOQuery1 содержит набор данных, то понятное дело, но тогда наужно использовать метод Open или Active := true. Вы понимаете, для чего нужен метод ExecSQL?
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.