В операции должен использоваться обновляемый запрос как исправить

Thirteen years later I face the same issue. DISTINCTROW did not solve my problem, but dlookup did.

I need to update a table from an aggregate query. As far as I understand, MS Access always assumes that de junction between the to-update table and the aggregate query is one-to-many., even though unique records are assured in the query.

The use of dlookup is:

DLOOKUP(Field, SetOfRecords, Criteria)

Field: a string that identifies the field from which the data is retrieved.

SetOfRecords: a string that identifies the set o record from which the field is retrieved, being a table name or a (saved) query name (that doesn’t require parameters).

Criteria: A string used to restrict the range of data on which the DLookup function is performed, equivalent to the WHERE clause in an SQL expression, without the word WHERE.

Remark

If more than one field meets criteria, the DLookup function returns the first occurrence. You should specify criteria that will ensure that the field value returned by the DLookup function is unique.

The query that worked for me is:

UPDATE tblTarifaDeCorretagem 
   SET tblTarifaDeCorretagem.ValorCorretagem = 
    [tblTarifaDeCorretagem].[TarifaParteFixa]+
    DLookUp(
     "[ParteVariável]",
     "cstParteVariavelPorOrdem",
     "[IdTarifaDeCorretagem] = " & [tblTarifaDeCorretagem].[IdTarifaDeCorretagem]
    );

Кротяка

7 / 7 / 1

Регистрация: 20.12.2010

Сообщений: 392

1

В операции должен использоваться обновляемый запрос

21.07.2014, 09:27. Показов 9632. Ответов 10

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Делаю запрос на обновление. Я хочу, чтобы на форме я мог из списка выбирать редактируемое поле, присваивать ему значение, затем выбирать поле для условия отбора и вписывать это условие…Скажите пожалуйста, можно ли как то это сделать? Вот как пытаюсь, но выдаёт, что запрос не обновляемый…

SQL
1
2
UPDATE тГости SET Forms!фРедактор.Параметр1.[VALUE] = Forms!фРедактор.Значение1.Value
WHERE Forms!фРедактор.Параметр2.Value=Forms!фРедактор.Значение2.Value;



0



mobile

Эксперт MS Access

26783 / 14462 / 3192

Регистрация: 28.04.2012

Сообщений: 15,782

21.07.2014, 09:45

2

Так, как Вы хотите, можно сделать в динамически создаваемом запросе в коде процедуры на ВБА.

Visual Basic
1
2
3
4
Dim s
s="UPDATE тГости SET [" & Forms!фРедактор.Параметр1 & "] = " & Forms!фРедактор.Значение1 _ 
& " WHERE [" & Forms!фРедактор.Параметр2 & "] = " & Forms!фРедактор.Значение2
Currentdb.Execute s

Учтите зависимость от типа поля. Если поле текстовое, то параметры должны подаваться в апострофах, если датное, то в специальном американском формате и в решетках.

ЗЫ. Свойство Value умолчательное для поля и поэтому его можно не писать



1



7 / 7 / 1

Регистрация: 20.12.2010

Сообщений: 392

21.07.2014, 10:04

 [ТС]

3

mobile, это я знаю. Но вся загвоздка в том, что мне обязательно нужно, чтобы этот запрос существовал, как объект БД



0



mobile

Эксперт MS Access

26783 / 14462 / 3192

Регистрация: 28.04.2012

Сообщений: 15,782

21.07.2014, 10:26

4

Лучший ответ Сообщение было отмечено Кротяка как решение

Решение

Цитата
Сообщение от Кротяка
Посмотреть сообщение

мне обязательно нужно, чтобы этот запрос существовал, как объект БД

Вариант с присвоением значения свойству SQL сохраненного запроса подходит?

Visual Basic
1
2
3
4
Dim s
s="UPDATE тГости SET [" & Forms!фРедактор.Параметр1 & "] = " & Forms!фРедактор.Значение1 _ 
& " WHERE [" & Forms!фРедактор.Параметр2 & "] = " & Forms!фРедактор.Значение2
Currentdb.QueryDefs("ИмяСохраненногоЗапроса").SQL=s



1



7 / 7 / 1

Регистрация: 20.12.2010

Сообщений: 392

21.07.2014, 10:55

 [ТС]

5

mobile, в принципе да. Спасибо



0



kirikys

0 / 0 / 0

Регистрация: 08.02.2018

Сообщений: 3

08.02.2018, 10:43

6

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Sub getdirfiles()
    Dim cn As Object, rs1 As Object
    
    Dim d, pth, strs, path
    Dim SQL$
    Set cn = CreateObject("ADODB.Connection")
    Set rs1 = CreateObject("ADODB.Recordset")
    cn.ConnectionString = "Driver={SQL Server Native Client 11.0};Server=192.168***;Database=***;Uid=***;Pwd=***;" 
    cn.Open
    path = "C:Users***"
    pth = path & "*.xlsm"
    d = Dir(pth)
    Do While d <> ""
        strs = "UPDATE [dbo_Dannue] " & _
      " SET [dbo_Dannue].[Clinika] = (select [Сводный$].[Clinika] from [Сводный$] IN '" & path & d & "'[Excel 8.0;HDR=YES;IMEX=2] " & _
      "),[dbo_Dannue].[Opl] = (select [Сводный$].[Opl] from [Сводный$] IN '" & path & d & "'[Excel 8.0;HDR=YES;IMEX=2]" & _
      "),[dbo_Dannue].[Kred] = (select [Сводный$].[Kred] from [Ñâîäíûé$] IN '" & path & d & "'[Excel 8.0;HDR=YES;IMEX=2] " & _
      "),[dbo_Dannue].[ProsKred] = (select [Сводный$].[ProsKred] from [Сводный$] IN '" & path & d & "'[Excel 8.0;HDR=YES;IMEX=2] " & _
      "),[dbo_Dannue].[Vurychka] =(select [Сводный$].[Vurychka] from [Сводный$] IN '" & path & d & "'[Excel 8.0;HDR=YES;IMEX=2]" & _
      "),[dbo_Dannue].[Nachisl] = (select [Сводный$].[Nachisl] from [Сводный$] IN '" & path & d & "'[Excel 8.0;HDR=YES;IMEX=2]" & _
      "),[dbo_Dannue].[Prixod] = (select [Сводный$].[Prixod] from [Сводный$] IN '" & path & d & "'[Excel 8.0;HDR=YES;IMEX=2]" & _
      "),[dbo_Dannue].[Vydacha] = (select [Сводный$].[Vydacha] from [Сводный$] IN '" & path & d & "'[Excel 8.0;HDR=YES;IMEX=2]" & _
      "),[dbo_Dannue].[Rasxod] = (select [Сводный$].[Rasxod] from [Сводный$] IN '" & path & d & "'[Excel 8.0;HDR=YES;IMEX=2]" & _
      "),[dbo_Dannue].[Ost_Skl] = (select [Сводный$].[Ost_Skl] from [Сводный$] IN '" & path & d & "'[Excel 8.0;HDR=YES;IMEX=2]" & _
      "),[dbo_Dannue].[Ost_Kab] = (select [Сводный$].[Ost_Kab] from [Сводный$] IN '" & path & d & "'[Excel 8.0;HDR=YES;IMEX=2] " & _
      ") WHERE [dbo_Dannue].[Mes_Year] = (select [Сводный$].[Mes_Year] from [Сводный$] IN '" & path & d & "'[Excel 8.0;HDR=YES;IMEX=2]);"
        
        Debug.Print strs
        Stop
        
        CurrentDb.Execute strs
        d = Dir
    Loop
    cn.Close
End Sub

Помогите пожалуйста. Никак не могу найти в чем причина ошибка(см.скрин)

Миниатюры

В операции должен использоваться обновляемый запрос
 



0



Модератор

Эксперт MS Access

5164 / 2564 / 637

Регистрация: 12.06.2016

Сообщений: 6,821

08.02.2018, 10:46

7

Запросы с подзапросами являются необновляемыми.



0



Эксперт MS Access

17217 / 7069 / 1582

Регистрация: 21.06.2012

Сообщений: 13,260

08.02.2018, 10:47

8

Вопрос по SQL Server, зачем задавать его здесь?



0



0 / 0 / 0

Регистрация: 08.02.2018

Сообщений: 3

08.02.2018, 10:54

9

Re: В операции должен использоваться обновляемый запрос
Вопрос по SQL Server, зачем задавать его здесь?

База на SQL сервере, а Accesse является юзерским интерфейсом.

Запросы с подзапросами являются необновляемыми.

Можно поподробнее, или ссылку где можно почитать. Заранее спасибо.



0



Эксперт MS Access

17217 / 7069 / 1582

Регистрация: 21.06.2012

Сообщений: 13,260

08.02.2018, 10:58

10

Цитата
Сообщение от kirikys
Посмотреть сообщение

База на SQL сервере, а Accesse является юзерским интерфейсом.

Запрос необновляемый где – на SQL сервере, причем здесь Jet SQL, с которым работает Акссесс. Какая разница, на чем у Вас сделана морда. Так понятнее?



0



Модератор

Эксперт MS Access

5164 / 2564 / 637

Регистрация: 12.06.2016

Сообщений: 6,821

08.02.2018, 11:02

11

Цитата
Сообщение от kirikys

Можно поподробнее, или ссылку где можно почитать.

Вот, например:
Why is my query read-only?



0



В Access 2013 пытаюсь создать запрос для заполнения поля СР_балл:

UPDATE Студент t1 SET t1.СР_балл = (SELECT AVG(Оценка) 
FROM Успеваемость t2 WHERE t2.ИН_Студ = t1.ИН_Студ)

но всё время эта ошибка:

В операции должен использоваться
обновляемый подзапрос

задан 5 фев 2015 в 18:14

Человек's user avatar

2

UPDATE Студент as t1 SET t1.СР_балл = (
    SELECT AVG(Оценка) FROM Успеваемость as t2 WHERE t2.ИН_Студ = t1.ИН_Студ
)

ответ дан 25 сен 2015 в 21:17

PrimusIP's user avatar

PrimusIPPrimusIP

3001 серебряный знак7 бронзовых знаков

Попробуй вот так:

UPDATE Студент t1 SET t1.СР_балл = AVG(t2.Оценка) 
FROM Успеваемость t2 WHERE t2.ИН_Студ = t1.ИН_Студ

ответ дан 6 фев 2015 в 6:16

namak7's user avatar

namak7namak7

1791 серебряный знак12 бронзовых знаков

2

Я получаю сообщение об ошибке: “Операция должна использовать обновляемый запрос” при попытке запустить мой SQL. Насколько я понимаю, это происходит, когда соединения используются в запросах обновления/удаления в MS Access. Тем не менее, я немного запутался, потому что у меня есть другой запрос, почти идентичный в моей базе данных, который отлично работает.

Это мой сложный запрос:

UPDATE [GS] INNER JOIN [Views] ON 
    ([Views].Hostname = [GS].Hostname) 
    AND ([GS].APPID = [Views].APPID) 
    SET 
        [GS].APPID = [Views].APPID, 
        [GS].[Name] = [Views].[Name], 
        [GS].Hostname = [Views].Hostname, 
        [GS].[Date] = [Views].[Date], 
        [GS].[Unit] = [Views].[Unit], 
        [GS].[Owner] = [Views].[Owner];

Как я уже говорил, я смущен, потому что у меня есть другой запрос, похожий на этот, который работает отлично. Это тот запрос:

UPDATE [Views] INNER JOIN [GS] ON 
[Views].APPID = [GS].APPID 
SET 
    [GS].APPID = [Views].APPID, 
    [GS].[Name] = [Views].[Name], 
    [GS].[Criticial?] = [Views].[Criticial?], 
    [GS].[Unit] = [Views].[Unit], 
    [GS].[Owner] = [Views].[Owner];

Что случилось с моим первым запросом? Почему второй запрос работает, когда первый не работает?

4b9b3361

Ответ 1

Является ли этот ответ общепринятым или нет, я не знаю, но я решил это, слегка изменив свой запрос.

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

Ответ 2

В коде отсутствует ошибка, но ошибка возникает из-за следующего:

 - Please check whether you have given Read-write permission to MS-Access database file.
 - The Database file where it is stored (say in Folder1) is read-only..? 

Предположим, что вы сохранили базу данных (файл MS-Access) в папке только для чтения, а при запуске приложения соединение не открывается полностью. Следовательно, измените разрешение файла/его разрешение на папку, например, в C:Program files, все большинство файлов c cd установлены только для чтения, поэтому изменение этого разрешения разрешает эту проблему.

Ответ 3

У меня была такая же ошибка при попытке обновить связанную таблицу.

Проблема заключалась в том, что связанная таблица не имела PRIMARY KEY.

После добавления ограничения первичного ключа на стороне базы данных и повторной привязки этой таблицы к проблеме доступа было решено.

Надеюсь, это поможет кому-то.

Ответ 4

У меня была такая же проблема в точности, и я не могу вспомнить, как я люблю это решение, но просто добавив DISTINCTROW решение проблемы.

В вашем коде это будет выглядеть так:

UPDATE DISTINCTROW [GS] INNER JOIN [Views] ON <- the only change is here
    ([Views].Hostname = [GS].Hostname) 
    AND ([GS].APPID = [Views].APPID) 
 ...

Я не уверен, почему это работает, но для меня он сделал именно то, что мне нужно.

Ответ 5

установить разрешение на каталог приложения решить эту проблему со мной

Чтобы установить это разрешение, щелкните правой кнопкой мыши папку App_Data (или любую другую папку, в которую вы положили файл), и выберите “Свойства”. Найдите вкладку “Безопасность”. Если вы не видите его, вам нужно перейти в “Мой компьютер”, затем “Инструменты” и “Параметры папки”…. затем перейдите на вкладку “Вид”. Прокрутите страницу вниз и снимите флажок “Использовать простой общий доступ к файлам (рекомендуется)”. Вернитесь на вкладку “Безопасность”, вам нужно добавить соответствующую учетную запись в поле “Группы” или “Имена пользователей”. Нажмите “Добавить”…. затем “Дополнительно”, затем “Найти сейчас”. Соответствующая учетная запись должна быть указана. Дважды щелкните его, чтобы добавить его в поле “Группа” или “Имена пользователей”, а затем установите флажок “Изменить” в разрешениях. Это. Вы закончили.

Ответ 6

Чтобы обновить записи, вам необходимо записать изменения в файл .mdb на диске. Если ваше сетевое/общее приложение не может записывать на диск, вы не можете обновлять существующие или добавлять новые записи. Таким образом, включите доступ для чтения/записи в папке базы данных или переместите базу данных в другую папку, в которой у вашего приложения есть разрешение на запись…. более подробно, пожалуйста, проверьте:

http://www.beansoftware.com/ASP.NET-FAQ/Operation-Must-Use-An-Updateable-Query.aspx

Ответ 7

Я использовал временную таблицу и, наконец, получил это, чтобы работать. Вот логика, которая используется после создания таблицы temp:

UPDATE your_table, temp
SET your_table.value = temp.value
WHERE your_table.id = temp.id

Ответ 8

Я обращался к базе данных с использованием UNC-пути, и иногда это исключение было брошено. Когда я заменил имя компьютера IP-адресом, проблема была внезапно решена.

Ответ 9

Это выстрел в темноте, но попробуйте поместить два операнда для символа AND в круглых скобках

Вкл. ((A = B) И (C = D))

Ответ 10

Я получил эту же ошибку, и использование первичного ключа не имело значения. Проблема заключалась в том, что таблица является связанной таблицей Excel. Я знаю, что есть настройки, чтобы изменить это, но мой ИТ-отдел заблокировал это, поэтому мы не можем изменить его. Вместо этого я создал таблицу make из связанной таблицы и использовал ее вместо этого в своем запросе на обновление, и это сработало. Обратите внимание, что любые запросы в вашем запросе, которые также связаны с той же самой связанной таблицей Excel, вызовут ту же ошибку, поэтому вам нужно будет также изменить их, чтобы они не были напрямую связаны со связанной таблицей Excel. НТН

Ответ 11

UPDATE [GS] INNER JOIN [Views] ON 
([Views].Hostname = [GS].Hostname) 
AND ([GS].APPID = [Views].APPID) <------------ This is the difference 
SET 
    [GS].APPID = [Views].APPID, 
    [GS].[Name] = [Views].[Name], 
    [GS].Hostname = [Views].Hostname, 
    [GS].[Date] = [Views].[Date], 
    [GS].[Unit] = [Views].[Unit], 
    [GS].[Owner] = [Views].[Owner];

#mysql #vba #ms-access

Вопрос:

Я прочитал много возможных решений этой ошибки, даже некоторые из них здесь, но, похоже, моя проблема не относится к тому же жанру, что и их. Мой слишком прост, что действительно сбивает меня с толку.

Я использую Access 2013 в качестве внешнего интерфейса, MYSQL 8.0.23 на заднем конце и MYSQL ODBC connector 8.0.23 Win32.

Когда я запускаю (либо через VBA, либо непосредственно из запроса):

 UPDATE Account1 SET LC = (Select Land_Company from Parameters2)
 

Я понял ошибку. Если я просто запущу Select Land_Company from Parameters2 , он вернет 420. Если я тогда побегу:

 UPDATE Account1 SET LC = 420
 

это прекрасно работает.

Как в таблице Account1, так и в таблице Parameters2 есть PKs. В таблице Account1 есть одна и только одна запись. Я также пытался:

 UPDATE Account1 SET LC = (Select Land_Company from Parameters2) where ID=4
 

так что это может повлиять только на одну строку, так как идентификатор является первичным ключом. Я даже пытался:

 UPDATE DISTINCTROW Account1 SET LC = (Select Land_Company from Parameters2) where ID=4
 

что тоже не работает. Оба Счета1.LC и параметры.Land_Company являются INT, поэтому проблемы с конвертацией нет. Я упускаю из виду что-то простое?

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

 Update Account1 Set Other_Expenses=(Select Sum(Expenses.Amount) from Expenses INNER JOIN Accounts On Accounts.Account_Number=Expenses.Account Where Accounts.Account_Type=10 and Expenses.Account <> '60000345' and Expenses.Account <> '60000115' and Expenses.Account <> '60000270' and Expenses.Account <> '17000230' and Expenses.Account <> '60000015' and Expenses.Account <> '40000005' and Expenses.Account <> '40000035' and Expenses.Account <> '60000190' and Expenses.Land_Company =420 and Expenses.Date>= '2020-01-01' and Expenses.Date<= '2020-12-31')
 

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

Комментарии:

1. «Действительно простой запрос» на самом деле состоит из 2 запросов (примечание, в WHERE предложении может использоваться a NOT IN (...) , и в любом случае им обоим придется выполнять — вы рассматривали возможность их выполнения отдельно и параметризации внешнего с выводом внутреннего запроса?

Ответ №1:

Используйте выражение DLookup вместо подзапроса, чтобы извлечь это Land_Company значение из Parameters2 таблицы:

 UPDATE Account1 
SET LC = DLookup('Land_Company', 'Parameters2')
WHERE ID = 4;
 

Комментарии:

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

2. Обновить Счет1 Установить Другие расходы=(Выберите Сумму(Расходы. Сумма) из Расходов По ВНУТРЕННИМ Счетам ПРИСОЕДИНЕНИЯ На Счетах. Номер счета=Расходы. Учетная Запись, Где Учетные Записи. Тип счета=10 и Расходы. Счет <> «60000345» и расходы. Счет <> «60000115» и расходы. Счет <> «60000270» и расходы. Счет <> «17000230» и расходы. Счет <> «60000015» и расходы. Счет <> «40000005» и расходы. Счет <> «40000035» и расходы. Счет <> «60000190» и расходы. Земельная компания =420 и расходы. Дата>= ‘2020-01-01’ и расходы. Дата

3. Мое подозрение состояло в том, что подзапрос заставил Access рассматривать UPDATE его как не обновляемый. Поэтому я использовал DLookup для извлечения то же значение, которое было возвращено подзапросом. Сработало ли это?

4. @AllanHall сначала вы запускаете внутренний запрос и используете его выходные данные для параметризации внешнего запроса, если драйвер не позволит вам убить двух зайцев одним и тем же камнем.

5. Также.. WHERE ... AND Expenses.Account NOT IN ('600000345','600000115','600000270','17000230','600000015','40000005','40000035','600000190') AND ... 😉

Добавить комментарий