Резюме
Это известная ошибка, вызванная обновлениями Office, выпущенными 12 ноября 2019 года. Эта ошибка затрагивает все версии Microsoft Access, поддерживаемые в настоящее время (от Access 2010 до 365).
Эта ошибка была исправлена.
- Если вы используете C2R (Click-to-Run) версию Office, используйте «Обновить сейчас» :
- Access 2010 C2R: исправлено в сборке 7243.5000
- Access 2013 C2R: исправлено в сборке 5197.1000
- Access 2016 C2R: исправлено в сборке 12130.20390
- Access 2019 (v1910): исправлено в сборке 12130.20390
- Access 2019 (корпоративная лицензия): исправлено в сборке 10353.20037
- Ежемесячный канал Office 365: исправлено в сборке 12130.20390
- Office 365 полугодовой: исправлено в сборке 11328.20480
- Office 365, полугодовой расширенный: исправлено в сборке 10730.20422
- Office 365, ориентированный на полугодовой период: исправлено в сборке 11929.20494
- Если вы используете MSI-версию Office, установите обновление, соответствующее вашей версии Office. Все эти исправления были выпущены в Центре обновления Microsoft, поэтому достаточно установить все ожидающие обновления Windows :
пример
Вот минимальный пример воспроизведения:
- Создайте новую базу данных Access.
- Создайте новую пустую таблицу «Table1» с полем идентификатора по умолчанию и длинным целым полем «myint».
Выполните следующий код в Immediate Window редактора VBA:
CurrentDb.Execute "UPDATE Table1 SET myint = 1 WHERE myint = 1"
Ожидаемый результат : оператор успешно завершается.
Фактический результат с одним из установленных ошибок: Произошла ошибка 3340 во время выполнения («Запрос» поврежден).
Ссылки по теме:
90150000-006E-0409-0000-0000000FF1CE
... это-0409-
не так-0407-
.-006E-0409-
также. На обеих машинах установлен пакет обновления 1 для Microsoft Office 2013 (KB2850036).{90140000-0011-0000-0000-0000000FF1CE}
пакетный скрипт. Обратите внимание,{9014...
нет{9114..}
Самое простое решение
Для моих пользователей ждать выпуска исправлений от Microsoft почти месяц до 10 декабря не вариант. Также не происходит удаление оскорбительного обновления Microsoft на нескольких заблокированных правительством рабочих станциях.
Мне нужно применить обходной путь, но я не совсем в восторге от того, что предложила Microsoft - создание и замена запроса для каждой таблицы.
Решение состоит в том, чтобы заменить имя таблицы простым
(SELECT * FROM Table)
запросом непосредственно вUPDATE
команде. Это не требует создания и сохранения тонны дополнительных запросов, таблиц или функций.ПРИМЕР:
Перед:
После:
Это должно быть намного проще реализовать в нескольких базах данных и приложениях (и в дальнейшем откате).
источник
Это не проблема обновления Windows, а проблема, появившаяся в выпуске November Patch Tuesday Office. Изменения, устраняющие уязвимость системы безопасности, приводят к тому, что некоторые допустимые запросы сообщаются как поврежденные. Поскольку изменение было исправлением безопасности, оно влияет на ВСЕ сборки Office, включая 2010, 2013, 2016, 2019 и O365.
Ошибка была исправлена во всех каналах, но время доставки будет зависеть от того, на каком канале вы находитесь.
В выпусках MSI 2010, 2013 и 2016 гг. С корпоративной лицензией 2019 г. и полугодовом канале O365 исправление будет в сборке с декабрьским исправлением во вторник, 10 декабря. Для O365, ежемесячного канала и инсайдеров это исправление будет исправлено когда октябрьская вилка будет выпущена, в настоящее время запланировано на 24 ноября.
Для полугодового канала ошибка была введена в 11328.20468, который был выпущен 12 ноября, но не распространяется на всех сразу. Если вы можете, вы можете отложить обновление до 10 декабря.
Эта проблема возникает для запросов на обновление одной таблицы с указанными критериями (поэтому не следует затрагивать запросы других типов, а также запросы, которые обновляют все строки таблицы, или запрос, который обновляет набор результатов другого запроса). Учитывая это, самый простой обходной путь в большинстве случаев - изменить запрос на обновление, чтобы обновить другой запрос, который выбирает все из таблицы, вместо непосредственного обновления запроса.
Т.е. если у вас есть запрос вроде:
Затем создайте новый запрос (Query1), определенный как:
и обновите исходный запрос:
Официальная страница: Ошибка доступа: «Запрос поврежден»
источник
Временное решение этой проблемы зависит от используемой версии Access:
Обновление Access 2010, удаление KB4484127 Обновление
Access 2013, удаление KB4484119 Обновление
Access 2016, удаление KB4484113
Access 2019, ЕСЛИ ТРЕБУЕТСЯ (tbc). Понизьте версию 1808 (сборка 10352.20042) до версии 1808 (сборка 10351.20054). Обновление
Office 365 ProPlus с версии 1910 (сборка 12130.20344) до предыдущей сборки см. По адресу https://support.microsoft.com/en-gb/help/2770432/. как к Revert к ан-ранее-версии-оф-офис-2013 или офис-2016-CLIC
источник
Мы и наши клиенты боролись с этим последние два дня и, наконец, написали статью, в которой подробно обсуждали проблему и некоторые решения: http://fmsinc.com/MicrosoftAccess/Errors/query_is_corrupt/
В нем содержатся наши выводы о том, что это влияет на решения Access при выполнении запросов на обновление локальных таблиц, связанных таблиц Access и даже связанных таблиц SQL Server.
Это также влияет на решения, не относящиеся к Microsoft Access, использующие Access Database Engine (ACE) для подключения к базам данных Access с использованием ADO. К ним относятся приложения Visual Studio (WinForm), приложения VB6 и даже веб-сайты, которые обновляют базы данных Access на компьютерах, на которых никогда не было установлено приложение Access или Office.
Этот сбой может даже повлиять на приложения Microsoft, которые используют ACE, такие как PowerBI, Power Query, SSMA и т. Д. (Не подтверждено), и, конечно, другие программы, такие как Excel, PowerPoint или Word, использующие VBA для изменения баз данных Access.
В дополнение к очевидному удалению обновлений безопасности, вызывающих проблемы, мы также включаем некоторые параметры, которые невозможно удалить из-за разрешений или распространения приложений Access для внешних клиентов, чьи компьютеры находятся вне вашего контроля. Это включает в себя изменение всех запросов на обновление и распространение приложений Access с использованием Access 2007 (для розничной продажи или среды выполнения), поскольку обновления безопасности не влияют на эту версию.
источник
Используйте следующий модуль для автоматической реализации предложенного Microsoft обходного решения (используя запрос вместо таблицы). В качестве меры предосторожности, сначала сделайте резервную копию вашей базы данных.
Используйте,
AddWorkaroundForCorruptedQueryIssue()
чтобы добавить обходной путь иRemoveWorkaroundForCorruptedQueryIssue()
удалить его в любое время.Вы можете найти последний код в моем репозитории GitHub .
AddWorkaroundForCorruptedQueryIssue()
добавит суффикс_Table
ко всем несистемным таблицам, например, таблицаIceCreams
будет переименована вIceCreams_Table
.Он также создаст новый запрос, используя исходное имя таблицы, который выберет все столбцы переименованной таблицы. В нашем примере запрос будет назван
IceCreams
и будет выполнять SQLselect * from [IceCreams_Table]
.RemoveWorkaroundForCorruptedQueryIssue()
делает обратные действия.Я проверил это со всеми видами таблиц, включая внешние таблицы, не относящиеся к MDB (например, SQL Server). Но имейте в виду, что использование запроса вместо таблицы может привести к неоптимизированным запросам, выполняемым к серверной базе данных в определенных случаях, особенно если ваши исходные запросы, которые использовали таблицы, либо низкого качества, либо очень сложные.
(И, конечно же, в зависимости от вашего стиля кодирования, в вашем приложении также возможно что-то сломать. Поэтому после проверки того, что исправление обычно работает для вас, никогда не будет плохой идеей экспортировать все ваши объекты в виде текста и использовать некоторые находки и замены Волшебство, гарантирующее, что любые вхождения имен таблиц будут выполняться для запросов, а не для таблиц.)
В моем случае это исправление работает в основном без каких-либо побочных эффектов, мне просто нужно было вручную переименовать его
USysRibbons_Table
обратноUSysRibbons
, поскольку я не помечал его как системную таблицу при создании в прошлом.источник
TableDef.Attributes
и копируете ее в мой ответ;) и функция отмены является хорошей идеей (но старое и новое имя должны храниться в таблице, поскольку в зависимости от того, нет таблиц с суффиксом до переименования). Некоторые другие части неисправны (например, таблицы могут заканчиваться суффиксом, или newname уже используется илиOn Error Resume Next
не обрабатывает ошибки позже). Вы знаете RubberduckVBA ? Этот плагин может проверить ваш код и дает хорошие предложения по улучшению, помимо всех других функций.Для тех, кто хочет автоматизировать этот процесс с помощью PowerShell , я нашел несколько ссылок, которые могут оказаться полезными:
Обнаружение и удаление оскорбительных обновлений
Здесь есть скрипт PowerShell, доступный по адресу https://www.arcath.net/2017/09/office-update-remover, который ищет в реестре конкретное обновление Office (передается как число в КБ) и удаляет его с помощью вызова
msiexec.exe
, Этот сценарий анализирует оба идентификатора GUID из разделов реестра, чтобы создать команду для удаления соответствующего обновления.Одним из изменений, которое я бы предложил, было бы использование
/REBOOT=REALLYSUPPRESS
описанного в разделе Как удалить KB4011626 и других обновлений Office (дополнительная ссылка: https://docs.microsoft.com/en-us/windows/win32/msi/uninstall-patches ). Командная строка, которую вы строите, выглядит следующим образом:Команда для запуска скрипта будет выглядеть примерно так:
Запретить установку обновлений
Рекомендуемый подход, похоже, скрывает обновление . Очевидно, что это можно сделать вручную, но есть некоторые сценарии PowerShell, которые могут помочь в автоматизации. Эта ссылка: https://www.maketecheasier.com/hide-updates-in-windows-10/ описывает процесс подробно, но я подведу итоги здесь.
Используйте следующую команду, чтобы скрыть обновление по номеру КБ:
Hide-WUUpdate -KBArticleID KB4484127
Надеюсь, это поможет кому-то еще.
источник
VBA-скрипт для MS-решения:
Рекомендуется удалить исправленное обновление, если это возможно (если не попробовать мой код), по крайней мере для версий MSI. Смотрите ответ https://stackoverflow.com/a/58833831/9439330 .
Для версий CTR (Click-To-Run) необходимо удалить все обновления Office за ноябрь, что может вызвать серьезные проблемы с безопасностью (не уверен, будут ли удалены какие-либо критические исправления).
Из комментариев @ Эрика:
Table.Tablename
для связывания форм, они освобождаются, так как прежнее имя таблицы теперь является именем запроса !.OpenRecordSet(FormerTableNowAQuery, dbOpenTable)
потерпит неудачу (так как теперь это запрос, а не таблица)Внимание! Просто быстрая проверка на Northwind.accdb на Office 2013 x86 CTR Нет гарантии!
Для тестирования:
источник
Inventory to reorder Subform for Home
сInventory
таблицей вHome
форме, без проблем. Даже не рекомендуется привязывать формы к запросам, а не к таблицам (не привязывается ли к таблицам какSelect * From table
?).Table.TableName
обозначения. Если вы делаетеSELECT * FROM TableName
вместо этого, вы, конечно, в порядке. Но если вы используетеTable.TableName
, ваша подчиненная форма станет несвязанной, если вы переименуете таблицу.TableDefs!MyTableName.OpenRecordset(dbOpenTable)
(поддержка поиска по индексу), которое я также склонен использовать, и это также приведет к ошибкам при вашем подходеЯ заменил
currentDb.Execute
иDocmd.RunSQL
с вспомогательной функцией. Это может предварительно обработать и изменить оператор SQL, если какой-либо оператор обновления содержит только одну таблицу. У меня уже естьdual
таблица (одна строка, один столбец), поэтому я выбрал опцию fakeTable.Примечание : это не изменит ваши объекты запроса. Это поможет только выполнению SQL через VBA.
If you would like to change your query objects, use FnQueryReplaceSingleTableUpdateStatements and update your sql in each of your querydefs. Shouldn't be a problem either.
Это всего лишь концепция
(If it's a single table update modify the sql before execution)
. Приспособьте это согласно своим потребностям. Этот метод не создает запросы на замену для каждой таблицы (что может быть самым простым способом, но имеет свои недостатки. Т.е. проблемы с производительностью)+ Очки: Вы можете продолжать использовать этот помощник даже после того, как MS исправит ошибку, это ничего не изменит. В случае, если будущее принесет другую проблему, вы готовы к
pre-process
вашему SQL в одном месте. Я не пошел на метод удаления обновлений, потому что для этого требуется доступ администратора + потребуется слишком много времени, чтобы получить всех на правильную версию +, даже если вы удалите, групповая политика некоторых конечных пользователей снова устанавливает последнее обновление. Вы вернулись к той же проблеме.Если у вас есть доступ к исходному коду,
use this method
и вы на 100% уверены, что проблема не возникнет ни у какого конечного пользователя.Теперь просто CTRL+F
Поиск и замена
docmd.RunSQL
наhelper.Execute
Поиск и замена
[currentdb|dbengine|or your dbobject].execute
наhelper.execute
радоваться, веселиться!
источник
Хорошо, я тоже буду здесь, потому что, хотя эта ошибка была исправлена, это исправление еще не заполнилось полностью на различных предприятиях, где конечные пользователи могут не иметь возможности обновляться (например, мой работодатель ...)
Вот мой обходной путь для
DoCmd.RunSQL "UPDATE users SET uname= 'bob' WHERE usercode=1"
. Просто закомментируйте ошибочный запрос и введите код ниже.Я не могу сказать, что это красиво, но это делает работу.
источник