![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Получение первой записи в таблице [D6]
leonidus © (2008-03-31 12:59:00)Мне необходимо получить первую запись из таблицы Access и изменить в ней два поля, делаю так:
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select top 1 * from tab');
ADOQuery1.ExecSQL;
ADOQuery1.Close;
ADOQuery1.FieldByName('active_word').AsBoolean:=true;
ADOQuery1.FieldByName('status').AsString:='learning';
но получаю сообщение что поле не существует... "ADOQuery1.Close" ставил и после попытки изменения поля и перед ним, толку никакого. В чем может быть трабла?
Кщд (2008-04-03 07:42:00) [1]>ANB (01.04.08 17:28) [18]
>Есть обход - указать индекс в хинте index_desc или index_asc.
этот "обход" - прямая дорога к трудноуловимым ошибкам (не говоря о том, что оптимизатор может просто проигнорировать хинт)
порядок сортировки гарантирует только order by
как сканировать индекс - это внутреннее дело oracle и далеко не факт, что скан пойдет в естественном порядке
в целом, согласен, не ясно, отчего применение фильтра(предиката) перед сортировкой вызывает удивление
ANB (2008-04-01 17:28:00) [2]
> А оптимизатор решил, что ему проще сделать сначала rownum=1,
> а потом уже отсортировать полученную выборку.
> правда дело было на сервере...
Дык он так и должен работать. И в доке написано.
Класический тест для "опытных" ораклистов.
Сначала отрабатывает where потом сортировка. Выход - вложенный запрос. Оракл корректно все это понимает. Есть обход - указать индекс в хинте index_desc или index_asc. Тогда мона обойтись обычным запросом.
leonidus (2008-04-01 15:02:00) [3]clickmaker большое спасибо, разобрался
clickmaker (2008-04-01 13:53:00) [4]
> а что это за Format такой, как его использовать?
функция
Stmt := Format('select top %d * from tab WHERE tab.status=:Str2 ORDER BY tab.header', [NumRows]);
leonidus (2008-04-01 13:47:00) [5]исправил запрос с применением ORDER BY:
ADOQuery1.SQL.Add('select top 7 * from tab WHERE tab.status=:Str2 ORDER BY tab.header');
теперь вопрос к clickmaker, а что это за Format такой, как его использовать?
Reindeer Moss Eater (2008-04-01 13:23:00) [6]все решилось обертыванием одного запроса другим
Anatoly Podgoretsky (2008-04-01 13:21:00) [7]> Reindeer Moss Eater (01.04.2008 12:54:11) [11]
В топку такой интерпритатор и оптимизатор, который выдает неверные данные.
Sergey13 (2008-04-01 12:56:00) [8]> [11] Reindeer Moss Eater © (01.04.08 12:54)
> А оптимизатор решил, что ему проще сделать сначала rownum=1,
> а потом уже отсортировать полученную выборку
Так это стандартное поведение вроде для оракла.
Reindeer Moss Eater (2008-04-01 12:54:00) [9]потому что order by нету
был такой прикол.
рисую запрос с ордербаем и rownum=1 на оракле.
сижу, жду, что в выборку попадет то что хочу.
А оптимизатор решил, что ему проще сделать сначала rownum=1, а потом уже отсортировать полученную выборку.
правда дело было на сервере...
Ega23 (2008-04-01 12:53:00) [10]
> А почему "первая попавшаяся" запись, поясните пожалуйста?
Потому, что нет никакой гарантии, что запрос select * from table будет выдавать строго одну и ту же выборку.
Кстати, под Postgres впервые это увидел - реально без сортировки на select * приходят разные выборки.
clickmaker (2008-04-01 12:50:00) [11]
> [8] leonidus (01.04.08 12:45)
> А почему "первая попавшаяся" запись, поясните пожалуйста?
потому что order by нету
> то получаю ошибку "ошибочное или пропущенное зарезервированное
> слово или аргумент в конструкции SELECT"...
top может быть только константой
используй Format
leonidus (2008-04-01 12:45:00) [12]А почему "первая попавшаяся" запись, поясните пожалуйста?
И еще один момент, не догоняю на счет параметров:
если делаю так:
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select top 7 * from tab WHERE tab.status=:Str2');
ADOQuery1.Parameters.ParamByName('Str2').Value:='learning';
ADOQuery1.Open;
но все нормально, однако стоит сделать так:
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select top :Str1 * from tab WHERE tab.status=:Str2');
ADOQuery1.Parameters.ParamByName('Str1').Value:=kol_learning_words;
ADOQuery1.Parameters.ParamByName('Str2').Value:='learning';
ADOQuery1.Open;
то получаю ошибку "ошибочное или пропущенное зарезервированное слово или аргумент в конструкции SELECT"...
Правильный_Вася (2008-03-31 14:06:00) [13]это не первая запись, это первая попавшаясязапись
Anatoly Podgoretsky (2008-03-31 13:47:00) [14]> leonidus (31.03.2008 12:59:00) [0]
О какой такой еще первой записи идет речь, когда здесь выбирается всего одна и та произвольная.
Sergey13 (2008-03-31 13:30:00) [15]> [4] leonidus (31.03.08 13:28)
> Всем спасибо, вот работающий код:
Остается понять что же он будет делать. 8-)
leonidus (2008-03-31 13:28:00) [16]Всем спасибо, вот работающий код:
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select top 1 * from tab');
ADOQuery1.Open;
ADOQuery1.Edit;
ADOQuery1.FieldByName('active_word').AsBoolean:=true;
ADOQuery1.FieldByName('status').AsString:='learning';
ADOQuery1.Post;
ADOQuery1.Close;
Sergey13 (2008-03-31 13:06:00) [17]> [0] leonidus (31.03.08 12:59)
> толку никакого. В чем может быть трабла?
В отсутствии понимания того, что делаешь.
Датасет перед редактированием желательно переводить в режим редактирования. А после редактирования желательно фиксировать изменения.
Reindeer Moss Eater (2008-03-31 13:02:00) [18]В том, что после закрытия экземпляры полей уничтожаются
clickmaker (2008-03-31 13:01:00) [19]
> ADOQuery1.ExecSQL;
> ADOQuery1.Close;
первое замени на Open;
второе только после изменения
лучше обернуть в try - finally