Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: UPDATE в Access  (Прочитано 19624 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
PAHAN
Гость
« : 30-10-2004 15:01 » 

Как заставить Запрос на обновление  понимать групповые операции?
Есть две таблицы: Абонент, Выдача так что один абонент имеет много выданных ему "объектов". Необходимо снимать деньги со счёта абонента в зависимости от количества выданных ему "объектов", проблема в том Access в упор не видит Сount в запросах на обновление(или это я еще не дорос до этого?) т.е код типа

UPDATE Абонент INNER JOIN Выдача ON Абонент.[абонент id]=Выдача.[абонент id]
SET Абонент.кредит = [кредит]-5*Count(Выдача.[диск id]);

или
UPDATE Абонент, Выдача
SET Абонент.кредит = [кредит]-5*Count(Выдача.[диск id])
WHERE Абонент.[абонент id]=Выдача.[абонент id];


говоря простым языком "не катит".Что можете посоветовать?
Записан
Mouse
Молодой специалист

ru
Offline Offline

« Ответ #1 : 01-11-2004 07:14 » 

PAHAN, вот что говорит SQL Server:
Код:

Server{ Msg 157, Level 15, State 1, Line 3
An aggregate may not appear in the set list of an UPDATE statement.


Так что тут облом, использовать COUNT в запросе UPDATE не получится...   Здесь была моя ладья...
Насколько я понял, этим запросом ты хочешь снять деньги со счета клиента за купленные диски? Тогда я бы предложил тебе другое решение: деньги со счета лучше снимать сразу же после покупки диска, причем для каждого купленного диска производить эту операцию отдельно.
Записан
mixa
Гость
« Ответ #2 : 01-11-2004 09:17 » 

Слушай,а если заменить Count(Выдача.[диск id]) на вызов вложенного SELECT-а.


Код:
UPDATE Абонент, Выдача 
SET Абонент.кредит = [кредит(-5*)SELECT Count)ВыдачаВВ.[диск id(:  from ВыдачаВВ Выдача WHERE ВыдачаВВ.[абонент id( = Абонент.[абонент id(:
WHERE Абонент.[абонент id(=Выдача.[абонент id(;


Для каждой строчки из Абонента перед записью будет вызван подзапрос - причем поле Абонент.[абонент id] будет подставленно из внешнего запроса !!!
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 01-11-2004 10:39 » 

UPDATE ни в коем разе не будет считать COUNT, и забудьте про это. Все групповые операции делаются только в SELECT. В данном случе обновляется лишь одна определённая запись и известным ID. Можно получить значение в переменную и потом уже сделать UPDATE.

Предложенный выше метод точно будет работать в SQL Server, однако за Access не поручусь - надо попробовать.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Mouse
Молодой специалист

ru
Offline Offline

« Ответ #4 : 01-11-2004 11:15 » 

mixa, поправь, если я ошибаюсь, но в UPDATE нельзя писать больше одной таблицы... А почему в данном случае в подзапрос будет подставляться ID из внешнего запроса? Ты прогонял этот код?

dimka, UPDATE будет считать COUNT, если его включать в виде подзапроса
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 02-11-2004 07:40 » 

Mouse,
1) правильный синтаксис
Код:

UPDATE [Абонент(
SET [Абонент(.[кредит( = ...
FROM [Выдача(
WHERE [Абонент(.[абонент id( = [Выдача(.[абонент id( AND [Выдача(.[...( = ...

но Access не поддерживает секцию FROM, т.е. обновление можно делать только по данным одной таблицы

2) правильный запрос
Код:

UPDATE [Абонент(
SET [Абонент(.[кредит( = [Абонент(.[кредит( - 5 * )SELECT COUNT)*: FROM [Выдача( WHERE [Абонент(.[абонент id( = [Выдача(.[абонент id(:

но в Access нельзя использовать подзапросы в команде UPDATE.

Единственный оставшийся путь: написать VBA-макрос, который отбирает нужные записи из [Абонента], затем в цикле по этим записям выполнять команды UPDATE, сформированный для каждой найденной. В теле цикла выполнять SELECT, получая количество и только потом делать UPDATE, подставляя это количество в тело запроса.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
PAHAN
Гость
« Ответ #6 : 02-11-2004 10:37 » 

спасибо всем кто откликнулся
Цитата: dimka

но Access не поддерживает секцию FROM, т.е. обновление можно делать только по данным одной таблицы.

слов нет, т.е они есть но нехорошие :@

Цитата: dimka


но в Access нельзя использовать подзапросы в команде UPDATE.

в курсе, поэтому и спрашивал про групповые онерации
Цитата: dimka


Единственный оставшийся путь: написать VBA-макрос, который отбирает нужные записи из [Абонента], затем в цикле по этим записям выполнять команды UPDATE, сформированный для каждой найденной. В теле цикла выполнять SELECT, получая количество и только потом делать UPDATE, подставляя это количество в тело запроса.

видимо так и придется, а ведь учебная задачка...
Записан
mixa
Гость
« Ответ #7 : 13-11-2004 14:50 » 

Народ - вот пример абсолютно рабочего куска
Код:
UPDATE file set nlink = )select count)*: from fs where sysnumfile = file.sysnum:;


В таблице file есть поле nlink, которое содержит число строк из таблицы fs, которые ссылаются на эту одну запись в таблице file по правилу  fs.sysnumfile = file.sysnum. В процессе работы, эта величина отслеживается автоматически, но иногда чтобы мне ничего не снилось я пересчитываю вот этим запросом. При построении таких запросов самая главная задача написать внутрений запрос так, чтобы при любом значении параметров он возвращал единственное значение. То есть в результате была бы одна строка.

Да. Есть возможность передать параметер из внешнего запроса во внутрений.

Единственное за что я извиняюсь - я не знал что такая крутая вещь как ODBC и Access не поддерживают вложенных запросов. Этот кусок гоняется на POSTGRES уже года так 4.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 13-11-2004 15:40 » new

Я не пробовал через ODBC или ADO, я пробовал только из самого Access. По идее, разницы быть не должно, но практика показывает, что иногда разница всё ж имеется. Из любопытства можно попробовать, но, думается, не поможет. Access слишком упрощён.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines