Проблема с UPDATE

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
alex shestov
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 25.04.2005 (Пн) 12:01

Проблема с UPDATE

Сообщение alex shestov » 25.04.2005 (Пн) 12:16

Проблема следующего плана: Нужно обновить две записи в таблице. Записи приходят из ряда запросов построенных друг над другом. Сами запросы отлично работают но когда нужно обновить результирующую таблицу - обновляю вот этим кодом:
UPDATE Deals_TMP
INNER JOIN NKD_DltDate ON (Deals_TMP.Number = NKD_DltDate.Number)
AND (Deals_TMP.Emitent = NKD_DltDate.Emitent)
SET Deals_TMP.NKD_on_date = Round(Round(((1000*(Deals_TMP![Cupon %]/100))*(NKD_DltDate!DltDate1/365)),2)*((NKD_DltDate!DltDate2/NKD_DltDate!DltDate1)),2)*NKD_DltDate!Nepogasheni_Nominal,
Deals_TMP.NKD = IIf(IsNull(NKD_DltDate!DltDate3),0,NKD_DltDate!Nepogasheni_Nominal*Round((Round((1000*((Deals_TMP![Cupon %]/100))*(NKD_DltDate!DltDate1)/365),2))*(NKD_DltDate!DltDate3/NKD_DltDate!DltDate1),2));
то выдает ошибку "В операции должен использоваться обновляемый запрос"

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

У меня есть предположение что проблема в запросе NKD_DltDate, вот он сам:
SELECT Deals_TMP.Number, Calendar.Id, Calendar.Date, Calendar.Emitent, Calendar.Nepogasheni_Nominal, Abs(NKD!Date-calendar!Date) AS DltDate1, Abs(Deals_TMP!Date_CF1-KD_DateMEAll![Max-Date]) AS DltDate2, Abs(Forms!MainForm!TodayDate-KD_0_!Date) AS DltDate3
FROM KD_0_
RIGHT JOIN (KD_DateMEAll
INNER JOIN (NKD INNER JOIN (Deals_TMP INNER JOIN Calendar ON Deals_TMP.Emitent = Calendar.Emitent)
ON NKD.Number = Deals_TMP.Number)
ON (KD_DateMEAll.Emitent = Deals_TMP.Emitent)
AND (KD_DateMEAll.Id = Calendar.Id))
ON KD_0_.Number = Deals_TMP.Number;
но не могу понять какая именно в нем проблема.

Помогите разобраться.
Спасибо огромное заранее.
Последний раз редактировалось alex shestov 25.04.2005 (Пн) 14:34, всего редактировалось 1 раз.

Sedge
Alternative Choice
Alternative Choice
Аватара пользователя
 
Сообщения: 1049
Зарегистрирован: 16.05.2002 (Чт) 18:23
Откуда: Somewhere-In-The-Net

Сообщение Sedge » 25.04.2005 (Пн) 13:18

UPDATE ... INNER JOIN - это как?

UPDATE <table> SET <field>=<field> FROM <table> INNER JOIN <table> ON <etc>

alex shestov
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 25.04.2005 (Пн) 12:01

Сообщение alex shestov » 25.04.2005 (Пн) 13:23

Sedge писал(а):UPDATE ... INNER JOIN - это как?

UPDATE <table> SET <field>=<field> FROM <table> INNER JOIN <table> ON <etc>


Запрос построен в Access-ом конструкторе и INNER JOIN появляется про связывании таблицы-получателя и запроса из которого берутся данные. Без этой связи по двум полям получается трех кратное увеличение резальтата (если сейчас у меня 4 правильных результата, то без двух связей, их уже 12, из которых 8 левых)

alex shestov
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 25.04.2005 (Пн) 12:01

Сообщение alex shestov » 25.04.2005 (Пн) 13:55

Причем, вот это нормально работает:
UPDATE KD_0_ INNER JOIN Deals_TMP ON (KD_0_.Number = Deals_TMP.Number) AND (KD_0_.Emitent = Deals_TMP.Emitent) SET Deals_TMP.KD = KD_0_!NKD;

Я почему и написал второй код, я так думаю что проблемы в нем.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 25.04.2005 (Пн) 13:59

Собственно, всё правильно...
Если запрос содержит вычисляемые поля, то он необновляемый. Обновляемый содержит прямые поля из базы.
А у тебя функция Abs :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

alex shestov
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 25.04.2005 (Пн) 12:01

Сообщение alex shestov » 25.04.2005 (Пн) 14:14

GSerg писал(а):Собственно, всё правильно...
Если запрос содержит вычисляемые поля, то он необновляемый. Обновляемый содержит прямые поля из базы.
А у тебя функция Abs :)


Сделал так - данные будут скидываться во временную таблицу, из которой уже будет обновляться основная. Это будет дольше, но раз выхода из данной ситайции нет - то буду пользоваться таким методом.

Спасибо за помощь всем откликнувшимся. :wink:

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 25.04.2005 (Пн) 14:18

Вообще-то при задании вопроса надо бы более-менее правильно его писать, например в данном вопросе нормально сформатировать текст запроса, чтобы его было удобно читать - вглядываться и расшифровывать текст идущий сплошняком совершенно нехочется...

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

Вообще-же подобный запрос построить можно, только выглядеть он должен примерно так:

Код: Выделить всё
UPDATE Deals_TMP SET NKD_on_date = ...
FROM ...
WHERE ...


Т.е нужно привести к такому синтаксису.
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

alex shestov
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 25.04.2005 (Пн) 12:01

Сообщение alex shestov » 25.04.2005 (Пн) 14:23

Andrey Fedorov писал(а):Вообще-то при задании вопроса надо бы более-менее правильно его писать, например в данном вопросе нормально сформатировать текст запроса, чтобы его было удобно читать - вглядываться и расшифровывать текст идущий сплошняком совершенно нехочется...

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

Вообще-же подобный запрос построить можно, только выглядеть он должен примерно так:

Код: Выделить всё
UPDATE Deals_TMP SET NKD_on_date = ...
FROM ...
WHERE ...


Т.е нужно привести к такому синтаксису.


Еххх....сорри, что так коряво написал... Думаю по кол-ву сообщений становится понятно что тут я вообще первый раз. В следующий - буду писать правильно.

А в чем дело, мне уже объяснили.

Интересно, можно ли обойтись без создания временной таблицы или в данном случае только так? Потому что без функции Abs он все равно не обновляет, т.к. там вычитание происходит. Можно или нет?

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 25.04.2005 (Пн) 14:29

alex shestov писал(а):Интересно, можно ли обойтись без создания временной таблицы или в данном случае только так? Потому что без функции Abs он все равно не обновляет, т.к. там вычитание происходит. Можно или нет?


Да это тут не причем. Значение вполне может вычисляться.

Я же написал выше как сделать.

А чтобы было конкретней - то нужна базка с табличками-запросами, чтобы можно было попробовать...
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

Sedge
Alternative Choice
Alternative Choice
Аватара пользователя
 
Сообщения: 1049
Зарегистрирован: 16.05.2002 (Чт) 18:23
Откуда: Somewhere-In-The-Net

Сообщение Sedge » 25.04.2005 (Пн) 14:31

alex shestov писал(а):Интересно, можно ли обойтись без создания временной таблицы

Скорее всего да. Для более точного ответа нужна структура таблиц и описание чего и откуда ты хочешь обновлять...

alex shestov
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 25.04.2005 (Пн) 12:01

Сообщение alex shestov » 25.04.2005 (Пн) 14:39

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

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 25.04.2005 (Пн) 14:59

Andrey Fedorov писал(а):Значение вполне может вычисляться.

Хочу. Хочу пример. Не видел, потому и хочу.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 25.04.2005 (Пн) 15:05

GSerg писал(а):Хочу. Хочу пример. Не видел, потому и хочу.


Ну вот и ты туда-же...
А Help по UPDATE глянуть? Там как раз пример с выражением есть:

Код: Выделить всё
UPDATE Заказы
SET КоличествоЗаказов = КоличествоЗаказов * 1.1,
Доставка = Доставка * 1.03
WHERE СтранаПоставщик = 'Великобритания'
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 25.04.2005 (Пн) 15:12

Ты не понял :)
В качестве обновляемого объекта используется запрос, возвративший вычисленные поля.
Приведи пример обновления таких полей, потому что именно такая проблема стоит перед человеком :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 25.04.2005 (Пн) 15:14

GSerg писал(а):Ты не понял :)
В качестве обновляемого объекта используется запрос, возвративший вычисленные поля.
Приведи пример обновления таких полей, потому что именно такая проблема стоит перед человеком :)


Там стоит:

UPDATE Deals_TMP ...

Как я понимаю Deals_TMP это таблица.
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 25.04.2005 (Пн) 15:21

Которая INNER JOIN с вычисляемым запросом :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 25.04.2005 (Пн) 15:25

GSerg писал(а):Которая INNER JOIN с вычисляемым запросом :)


Да чихать на этот запрос, по большому счету - он не критичен абсолютно. Можно еще так попробовать:

Код: Выделить всё
UPDATE Deals_TMP
    SET Deals_TMP.NKD_on_date = Round(Round(((1000*(Deals_TMP![Cupon %]/100))*(NKD_DltDate!DltDate1/365)),2)*((NKD_DltDate!DltDate2/NKD_DltDate!DltDate1)),2)*NKD_DltDate!Nepogasheni_Nominal,
        Deals_TMP.NKD = IIf(IsNull(NKD_DltDate!DltDate3),0,NKD_DltDate!Nepogasheni_Nominal*Round((Round((1000*((Deals_TMP![Cupon %]/100))*(NKD_DltDate!DltDate1)/365),2))*(NKD_DltDate!DltDate3/NKD_DltDate!DltDate1),2))
    FROM Deals_TMP, NKD_DltDate
    WHERE Deals_TMP.Number = NKD_DltDate.Number
      AND Deals_TMP.Emitent = NKD_DltDate.Emitent
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

Sedge
Alternative Choice
Alternative Choice
Аватара пользователя
 
Сообщения: 1049
Зарегистрирован: 16.05.2002 (Чт) 18:23
Откуда: Somewhere-In-The-Net

Сообщение Sedge » 25.04.2005 (Пн) 15:29

GSerg писал(а):Которая INNER JOIN с вычисляемым запросом :)

Не, INNER JOIN с вычисляемым запросом - это NKD_DltDate... Она в правой части апдейта стоит.
Это такая извращенная логика, я так понял, чтобы Deals_TMP из самой себя проапдейтить...

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 25.04.2005 (Пн) 15:43

NKD_DltDate - это и есть вычисляемый запрос :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 25.04.2005 (Пн) 15:44

GSerg писал(а):NKD_DltDate - это и есть вычисляемый запрос :)


Обновляется-то не он. А конкретная таблица.
Неужели мне пример лепить придется???
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

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

Сообщение alibek » 25.04.2005 (Пн) 15:50

Я несколько не в тему, просто небольшой комментарий хочу внести.

Если в запросе SELECT есть вычисляемые поля, то такой запрос является нередактируемым, т.е. его нельзя открыть и через него обновлять записи.

Моя ИМХА такая.
Результатом Deals_TMP INNER JOIN NKD_DltDate ON (Deals_TMP.Number = NKD_DltDate.Number) AND (Deals_TMP.Emitent = NKD_DltDate.Emitent) будет необновляемый запрос, оттого и ругается Access. Если запрос переписать, описав соединения не в FROM, а в WHERE, то запрос должен сработать.
Lasciate ogni speranza, voi ch'entrate.

alex shestov
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 25.04.2005 (Пн) 12:01

Сообщение alex shestov » 25.04.2005 (Пн) 15:50

Sedge писал(а):
GSerg писал(а):Которая INNER JOIN с вычисляемым запросом :)

Не, INNER JOIN с вычисляемым запросом - это NKD_DltDate... Она в правой части апдейта стоит.
Это такая извращенная логика, я так понял, чтобы Deals_TMP из самой себя проапдейтить...


Правильно. Мне нужно чтобы на каждую расчетную дату в Deals_TMP происходил расчет NKD_on_date (Накопленного купонного дохода), который изменяется каждый расчетный день. А почему там стоит RIGHT JOIN, потому что не все сделки на дату расчета имеют NKD_All (полученный КД ), и нужно чтобы в таблицу попали как те так и другие, а так как нужно высчитывать даты до погашения купона, то это делается в разных запросах, а в этом сливается в общую информацию по датам, из которых потом и высчитывается НКД.

alex shestov
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 25.04.2005 (Пн) 12:01

Сообщение alex shestov » 25.04.2005 (Пн) 15:55

GSerg писал(а):NKD_DltDate - это и есть вычисляемый запрос :)


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

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

Сообщение alibek » 25.04.2005 (Пн) 15:56

Помоему будет понятнее, если ты выложишь базу с пустыми таблицами. Я наверное плохо соображаю с понедельника, но никак ничего не пойму.
Lasciate ogni speranza, voi ch'entrate.

alex shestov
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 25.04.2005 (Пн) 12:01

Сообщение alex shestov » 25.04.2005 (Пн) 15:57

Andrey Fedorov писал(а):
GSerg писал(а):NKD_DltDate - это и есть вычисляемый запрос :)


Обновляется-то не он. А конкретная таблица.
Неужели мне пример лепить придется???


Если Вас не напряжёт, я бы с удовольствием посмотрел на пример.

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 25.04.2005 (Пн) 16:00

alibek писал(а):Если запрос переписать, описав соединения не в FROM, а в WHERE, то запрос должен сработать.


А, похоже тут не переписать - у Access-a инструкция UPDATE примитивна и не имеет FROM, так что облом...
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

alex shestov
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 25.04.2005 (Пн) 12:01

Сообщение alex shestov » 25.04.2005 (Пн) 16:04

Andrey Fedorov писал(а):
alibek писал(а):Если запрос переписать, описав соединения не в FROM, а в WHERE, то запрос должен сработать.


А, похоже тут не переписать - у Access-a инструкция UPDATE примитивна и не имеет FROM, так что облом...


Именно - выдает "Ошибка синтаксиса в варежении запроса" и указывает на From. :?

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 25.04.2005 (Пн) 16:04

Andrey Fedorov писал(а):Обновляется-то не он. А конкретная таблица.
Неужели мне пример лепить придется???

Andrey Fedorov писал(а):А, похоже тут не переписать - у Access-a инструкция UPDATE примитивна


Во-во :) О чём я и говорю :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

alex shestov
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 25.04.2005 (Пн) 12:01

Сообщение alex shestov » 25.04.2005 (Пн) 16:06

Схема со временной таблицой очень плоха? Или имеет место быть?
Т.к. будут пересчитываться только актуальные сделки, а больше тысячи их точно не будет....я надеюсь

alex shestov
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 25.04.2005 (Пн) 12:01

Сообщение alex shestov » 25.04.2005 (Пн) 16:34

Да чихать на этот запрос, по большому счету - он не критичен абсолютно. Можно еще так попробовать:

Код: Выделить всё
IIf(IsNull(NKD_DltDate!DltDate3),0,NKD_DltDate!Nepogasheni_Nominal*Round((Round((1000*((Deals_TMP![Cupon %]/100))*(NKD_DltDate!DltDate1)/365),2))*(NKD_DltDate!DltDate3/NKD_DltDate!DltDate1),2))
    FROM Deals_TMP, NKD_DltDate
    WHERE Deals_TMP.Number = NKD_DltDate.Number
      AND Deals_TMP.Emitent = NKD_DltDate.Emitent
[/quote]

В VB выдает Run-Time error 3075 - ошибка синтаксиса, и ругается на этот код. Как вы думает, в чем проблема?
В функции IsNull?
Последний раз редактировалось alex shestov 25.04.2005 (Пн) 16:35, всего редактировалось 1 раз.

След.

Вернуться в Visual Basic 1–6

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 133

    TopList