Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Получение первой записи в таблице [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


Наверх

Титульная страница Поиск, карта сайта Написать письмо