БД Access, поиск записей

Работа VB и СУБД (Access, MSSQL, MySQL, Oracle и пр.)
Правила форума
При создании новой темы не забывайте указывать используемую СУБД.
Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

БД Access, поиск записей

Сообщение Чудик » 21.03.2005 (Пн) 19:36

Использую в качестве БД базу Access. Проблема в следующем. Есть таблица, куда записываются наименования с индивидуальным кодом. Каждая такая запись имеет значение, как количество наименования.
При изменении количества одного из наименований открываем данную таблицу и, перемещаясь снизу вверх, ищем первую запись нужного наименования по коду (тем самым как бы ищем запись нужного наименования, которая была внесена в БД последней). При нахождении таковой записи меняем количество.
Данный алгоритм работает, но периодически вносятся неверные значения количества. Так как глюк не постоянный, найти и определить его составляет некую трудность. Грешу пока на сам алгоритм. Может не всегда находится именно запись, внесенная последней? Или, может, еще что-нибудь?
Пожалуйста, поделитесь своим мнением. Может, вообще, все не так организовать? В чем фишка?
Век живи - век учись!
www.detal-plast.narod.ru

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 22.03.2005 (Вт) 3:56

Я правильно понял, что термин foreign key (внешний ключ) тебе незнаком?

Н-да, надо же такое придумать... А как программа узнает, какое именно наименование ей надо отредактировать?

Алексей К.
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 12.05.2004 (Ср) 9:41
Откуда: Ульяновск

Сообщение Алексей К. » 22.03.2005 (Вт) 8:11

Если тебе всегда надо изменять именно последнее наименование (получаются что это не уникальные записи?). то добавь поле типа "счетчик" - автоинкрементное, и открывай recordset с сортировкой по счетчику. Ну а потом movelast и вперед..... А если они уникальные у тебя то нет смысла дублировать записи наименований, изменяй сразу через: update имя_таблицы set наеменование=новые_данные where наименование=нужное_тебе_наименование;

Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

Сообщение Чудик » 22.03.2005 (Вт) 8:27

Алексей К. - записи являются уникальными из-за количества + еще пару данных, которые необходимо сохранять как историю данного наименования каждого дня. Счетчик у меня стоит, но MoveLast не получается применить, так как видов наименований много (типа ручка, карандаш, стерка, бумага) и каждое наименование со своими данными за определенный день. Нужно именно найти среди всех записей, например карандаш, и чтобы эта запись была сделана среди записей про карандаш последней.
Ennor - что такое внешний ключ и зачем он?
Век живи - век учись!
www.detal-plast.narod.ru

Алексей К.
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 12.05.2004 (Ср) 9:41
Откуда: Ульяновск

Сообщение Алексей К. » 22.03.2005 (Вт) 9:05

select что_надо from table_name where наименование="карандаш" order by имя_поля_счетчика;
Потом movelast - попадешь на последнюю запись.
Если есть поле - дата такой же запрос по карандашу только по последней (максимальной) дате.

Tuco
Постоялец
Постоялец
 
Сообщения: 508
Зарегистрирован: 18.06.2003 (Ср) 16:37
Откуда: Подмосковье

Сообщение Tuco » 22.03.2005 (Вт) 11:53

Вариант:
поле id - счётчик

select max(id) from table_name where наименование="карандаш"

этот запрос вернёт самый свежий номер записи, а потом уже изменять поле с этим номером

а, возможно, пройдёт вариант с вложением запроса в запрос, типа:

select ... from table where id=(select max()...)

к сожалению, нет времени проверять... :-(
"There's more than one way to do it!"

Алексей К.
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 12.05.2004 (Ср) 9:41
Откуда: Ульяновск

Сообщение Алексей К. » 22.03.2005 (Вт) 12:22

Если просто надо изменить последнюю запись, то:
UPDATE таблица SET колво = "100" WHERE наименование="карандаш" and дата= (select max(дата) from таблица);

Tuco
Постоялец
Постоялец
 
Сообщения: 508
Зарегистрирован: 18.06.2003 (Ср) 16:37
Откуда: Подмосковье

Сообщение Tuco » 22.03.2005 (Вт) 14:02

вот-вот, примерно это я и имел в виду.... :-)
"There's more than one way to do it!"

Алексей К.
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 12.05.2004 (Ср) 9:41
Откуда: Ульяновск

Сообщение Алексей К. » 22.03.2005 (Вт) 15:19

Если кто-то начинает изучать запросы рекомендую сайт c упражнениями и учебной информацией по SQL, кто решит все упражнения - шарить в запросах будет точно :D
http://sql-ex.ru

Krasavica
Небожительница
Небожительница
Аватара пользователя
 
Сообщения: 1378
Зарегистрирован: 04.11.2003 (Вт) 17:51
Откуда: Россия, город-герой Москва ;-)

Сообщение Krasavica » 22.03.2005 (Вт) 16:45

Чудик

Я бы предложила Вам следующий алгоритм:

1. В таблицу добавляется уникальный ключ, который увеличивается при добавлении новой записи.
2. Поиск производить не перебором а запросом с условием где КОД = требуемому Вами значению и уникальный ключ максимальный.
3. Извенять найденную запись по Вашим условиям.

Проблемы:

1. Если с программой одновременно работают несколько пользователей, то есть возможнсоть что Вы внесёте изменения все же не в последнюю запись, т.к. в момент Ваших действий другие пользователи могут добавить записи в эту таблицу.
2. У Вас проблема вероятнее всего в том что, MS Access НЕ всегда может однозначно вернуть список записей в том порядке в котором они были добавлены, следовательно Ваш алгоритм проходу снизу-вверх НЕ всегда будет работать правильно.
я - ангел!!! ...просто крылья в стирке, а нимб на подзарядке!
Меня трудно найти, легко потерять и невозможно забыть.Изображение

Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

Сообщение Чудик » 22.03.2005 (Вт) 22:30

Спасибо, за активное участие в решение данного вопроса. Но чтобы убедиться в том, что проблема решена необходимо будет, как минимум день, наблюдения работы проги. Результаты обязательно сообщу.

Krasavica писал(а):Чудик

1. Если с программой одновременно работают несколько пользователей, то есть возможнсоть что Вы внесёте изменения все же не в последнюю запись, т.к. в момент Ваших действий другие пользователи могут добавить записи в эту таблицу.
.


Какие есть пути разрешения таковой ситуации?
Век живи - век учись!
www.detal-plast.narod.ru

Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

Сообщение Чудик » 22.03.2005 (Вт) 22:55

Да, к стати при
Код: Выделить всё
    rsSQL = "SELECT MAX(q) FROM UhodCR WHERE Index='" & .TextMatrix(MyRow, 1) & "';"
    Set rs = db.OpenRecordset(rsSQL)

        az = rs.Fields(2)

на последней приведенной строчке выдает, что "элемент не найден в данном семействе".
Век живи - век учись!
www.detal-plast.narod.ru

Алексей К.
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 12.05.2004 (Ср) 9:41
Откуда: Ульяновск

Сообщение Алексей К. » 23.03.2005 (Ср) 7:29

А у тебя в результате recordset содержит только одну запись (один столбец) - она представляет собой max(q). поэтому и ошибка - второго столбца то в recordset`e нет. А если хочешь посмотреть что у тебя в recordset`е - проверяй работу запросов в самом access`е (не из своей проги), если все нормально - загоняй код запроса в свою прогу.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 23.03.2005 (Ср) 8:11

Чудик писал(а):Да, к стати при
Код: Выделить всё
    rsSQL = "SELECT MAX(q) FROM UhodCR WHERE Index='" & .TextMatrix(MyRow, 1) & "';"
    Set rs = db.OpenRecordset(rsSQL)

        az = rs.Fields(2)

на последней приведенной строчке выдает, что "элемент не найден в данном семействе".

Потому что select max(q) выдает всего одно поле. А коллекция Fields начинается с нулевого элемента.
Пиши az=rs.Fields(0)
Lasciate ogni speranza, voi ch'entrate.

Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

Сообщение Чудик » 23.03.2005 (Ср) 10:22

Поля в таблице Data,Index,Stock,Prihod,q. Где q - счетчик.
Пишу:
Код: Выделить всё
    rsSQL = "SELECT*FROM UhodCR WHERE q=(select max(q) from UhodCR) AND Index='" & .TextMatrix(MyRow, 1) & "';"
    Set rs = db.OpenRecordset(rsSQL)


rs.MoveLast           

Выдает "Текущая запись отсутствует".
Но, то, что запись с таким Index есть, я уверен.
Век живи - век учись!
www.detal-plast.narod.ru

Алексей К.
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 12.05.2004 (Ср) 9:41
Откуда: Ульяновск

Сообщение Алексей К. » 23.03.2005 (Ср) 10:30

Значит запись с Index (1) который тебе надо не соответсвует max(q). Т.е. у записи с max(q) Index - другой не (1) . поэтому recordset пустой.
Проверяй запрос в Access если у тебя трудности возникают. (Запросы->Создать новый в режиме конструктора-> Вид->режим SQL-> пиши инструкцию SQL). Потом присвоишь имя запросу и запустишь его, ну и увидишь его результат...

Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

Сообщение Чудик » 23.03.2005 (Ср) 12:13

Да, стало понятней с проверкой инструкций. Получается, что в моем случае, чтобы найти самую последнюю запись про карандаш среди ручек, стерок и т.д. max вообще не нужен, а нужен order by, т.е., как я понимаю, явнре указание сортировки (не смотря на счетчик). Только всегда ли будет соблюдаться такая сортировка? Я слышал, что все равно бывают случаи, когда порядок записей возвращается в нарушенном порядке.
Век живи - век учись!
www.detal-plast.narod.ru

Алексей К.
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 12.05.2004 (Ср) 9:41
Откуда: Ульяновск

Сообщение Алексей К. » 23.03.2005 (Ср) 13:11

Order by имя_поля - сортирует результирующий запрос по полю - имя_поля. Укажещь order by q -сортировка по счетчику, order by q, data - отсортирует сначала по полю q потом по полю data.
В твоем случае чтобы найти самую последнюю запись про карандаш среди ручек, стерок и т.д.
Пиши запрос:
SELECT * FROM UhodCR WHERE q=(select max(q) from UhodCR) AND имя_поля_с_наименованием="карандаш";
И всегда будешь на последней записи, если есть поле стипом "дата" то:
SELECT * FROM UhodCR WHERE имя_поля_дата=(select max(имя_поля_дата) from UhodCR) AND имя_поля_с_наименованием="карандаш";

Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

Сообщение Чудик » 23.03.2005 (Ср) 13:30

Алексей К. писал(а):Пиши запрос:
SELECT * FROM UhodCR WHERE q=(select max(q) from UhodCR) AND имя_поля_с_наименованием="карандаш";
И всегда будешь на последней записи,

Так я выше и приводил, с указанием на вывод ошибки.
Век живи - век учись!
www.detal-plast.narod.ru

Алексей К.
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 12.05.2004 (Ср) 9:41
Откуда: Ульяновск

Сообщение Алексей К. » 23.03.2005 (Ср) 14:32

Ложанулся :oops:
А так попробуй:
1) сразу на последнюю запись
SELECT * FROM UhodCR WHERE q=(select max(q) from UhodCR WHERE имя_поля_с_наименованием="карандаш") AND имя_поля_с_наименованием="карандаш";

или
2) наборы записей для карандаша
SELECT * FROM UhodCR WHERE имя_поля_с_наименованием="карандаш" order by q;
потом rs.movelast

или

SELECT * FROM UhodCR WHERE имя_поля_с_наименованием="карандаш" order by имя_поля_дата;
потом rs.movelast

Krasavica
Небожительница
Небожительница
Аватара пользователя
 
Сообщения: 1378
Зарегистрирован: 04.11.2003 (Вт) 17:51
Откуда: Россия, город-герой Москва ;-)

Сообщение Krasavica » 23.03.2005 (Ср) 18:27

Чудик писал(а):Какие есть пути разрешения таковой ситуации?

Чудик писал(а):Да, к стати при
Код: Выделить всё
    rsSQL = "SELECT MAX(q) FROM UhodCR WHERE Index='" & .TextMatrix(MyRow, 1) & "';"
    Set rs = db.OpenRecordset(rsSQL)

        az = rs.Fields(2)

на последней приведенной строчке выдает, что "элемент не найден в данном семействе".


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

А насчёт ошибки, ну так у вас в результирующем курсоре только одно поле, а вы обращаетесь ко второму, вполне логично что его нет ;)
я - ангел!!! ...просто крылья в стирке, а нимб на подзарядке!
Меня трудно найти, легко потерять и невозможно забыть.Изображение

Inferno
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 179
Зарегистрирован: 26.01.2005 (Ср) 1:06

Сообщение Inferno » 24.03.2005 (Чт) 0:12

Я в аксессе знаток небольшой, но в мускуле выбрать 10 максимальных значения можно так
SELECT * FROM `table_name` ORDER BY `table_field` DESC LIMIT 10

10 минимальных

SELECT * FROM `table_name` ORDER BY `table_field` ASC LIMIT 10

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 24.03.2005 (Чт) 8:07

SELECT TOP 10 * ...
Lasciate ogni speranza, voi ch'entrate.

Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

Сообщение Чудик » 28.03.2005 (Пн) 11:13

Использую
rsSQL = "SELECT*FROM Prihod WHERE Index='" & .TextMatrix(MyRow, 1) & "' order by q;"
Из 100 наименований каждый день сбивается по значению одна или две позиции. Конечно, не как раньше (до десяти позиций доходило), но все равно не хорошо.
Как можно ужесточить контроль за порядком записей?
Век живи - век учись!
www.detal-plast.narod.ru


Вернуться в Базы данных

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 5

    TopList