Podsumowanie
Jest to znany błąd spowodowany aktualizacjami pakietu Office wydanymi 12 listopada 2019 r. Błąd dotyczy wszystkich wersji Access obecnie obsługiwanych przez Microsoft (od Access 2010 do 365).
Ten błąd został naprawiony.
- Jeśli używasz wersji pakietu Office C2R (Szybka instalacja), użyj opcji „Aktualizuj teraz” :
- Access 2010 C2R: Naprawiono w kompilacji 7243.5000
- Access 2013 C2R: Naprawiono w kompilacji 5197.1000
- Access 2016 C2R: Naprawiono w kompilacji 12130.20390
- Access 2019 (v1910): Naprawiono w kompilacji 12130.20390
- Access 2019 (licencja zbiorowa): Naprawiono w kompilacji 10353.20037
- Miesięczny kanał Office 365: Naprawiono w kompilacji 12130.20390
- Półroczne Office 365: Naprawiono w kompilacji 11328.20480
- Rozszerzone półroczne Office 365: Naprawiono w kompilacji 10730.20422
- Cel półroczny Office 365: Naprawiono w kompilacji 11929.20494
- Jeśli używasz wersji MSI pakietu Office, zainstaluj aktualizację zgodną z wersją pakietu Office. Wszystkie te poprawki zostały wydane w witrynie Microsoft Update, więc wystarczy zainstalować wszystkie oczekujące aktualizacje systemu Windows :
Przykład
Oto minimalny przykład repro:
- Utwórz nową bazę danych Access.
- Utwórz nową, pustą tabelę „Tabela 1” z domyślnym polem identyfikatora i polem Długa liczba całkowita „myint”.
Wykonaj następujący kod w oknie natychmiastowym edytora VBA:
CurrentDb.Execute "UPDATE Table1 SET myint = 1 WHERE myint = 1"
Oczekiwany wynik : Instrukcja zakończy się pomyślnie.
Rzeczywisty wynik po zainstalowaniu jednej z błędnych aktualizacji: pojawia się błąd 3340 w czasie wykonywania („Zapytanie” jest uszkodzone).
Powiązane linki:
90150000-006E-0409-0000-0000000FF1CE
... to-0409-
nie jest-0407-
.-006E-0409-
. Oba komputery mają zainstalowany dodatek Service Pack 1 dla pakietu Microsoft Office 2013 (KB2850036).{90140000-0011-0000-0000-0000000FF1CE}
skryptu wsadowego. Uwaga{9014...
nie{9114..}
Najprostsze rozwiązanie
Dla moich użytkowników czekanie prawie 10 miesięcy do 10 grudnia na wydanie poprawki od Microsoft nie wchodzi w grę. Odinstalowywanie nieuczciwej aktualizacji Microsoft na kilku rządowych stacjach roboczych jest również zablokowane.
Muszę zastosować obejście, ale nie do końca jestem podekscytowany tym, co Microsoft zasugerował - tworząc i zastępując zapytanie dla każdej tabeli.
Rozwiązaniem jest zastąpienie nazwy tabeli prostym
(SELECT * FROM Table)
zapytaniem bezpośrednio wUPDATE
poleceniu. Nie wymaga to tworzenia i zapisywania mnóstwa dodatkowych zapytań, tabel lub funkcji.PRZYKŁAD:
Przed:
Po:
Powinno to być o wiele łatwiejsze do wdrożenia w kilku bazach danych i aplikacjach (a później wycofaniu).
źródło
To nie jest problem z aktualizacją systemu Windows, ale problem, który został wprowadzony w wersji Office Patch z listopada. Zmiana mająca na celu usunięcie luki w zabezpieczeniach powoduje, że niektóre uzasadnione zapytania są zgłaszane jako uszkodzone. Ponieważ zmiana była poprawką bezpieczeństwa, ma wpływ na WSZYSTKIE wersje pakietu Office, w tym 2010, 2013, 2016, 2019 i O365.
Błąd został naprawiony we wszystkich kanałach, ale czas dostarczenia zależy od tego, na którym kanale jesteś.
W przypadku wersji MSI 2010, 2013 i 2016 oraz licencji półrocznych O365, poprawka będzie dostępna we wtorek, 10 grudnia, 10 grudnia. W przypadku O365, kanału miesięcznego i osób mających dostęp do informacji poufnych zostanie to naprawione kiedy pojawi się październikowy widelec, obecnie planowany na 24 listopada.
W przypadku kanału półrocznego błąd został wprowadzony w 11328.20468, który został wydany 12 listopada, ale nie jest dostępny dla wszystkich naraz. Jeśli możesz, możesz wstrzymać się z aktualizacją do 10 grudnia.
Problem występuje w przypadku zapytań o aktualizację dla pojedynczej tabeli z określonymi kryteriami (więc nie należy wpływać na inne typy zapytań, ani na zapytania, które aktualizują wszystkie wiersze tabeli, ani zapytania, które aktualizuje zestaw wyników innego zapytania). Biorąc to pod uwagę, najprostszym obejściem w większości przypadków jest zmiana zapytania aktualizacyjnego, aby zaktualizować inne zapytanie, które wybiera wszystko z tabeli, zamiast aktualizować zapytanie bezpośrednio.
To znaczy, jeśli masz zapytanie takie jak:
Następnie utwórz nowe zapytanie (Query1) zdefiniowane jako:
i zaktualizuj oryginalne zapytanie, aby:
Oficjalna strona: Błąd dostępu: „Zapytanie jest uszkodzone”
źródło
Aby tymczasowo rozwiązać ten problem, zależy od używanej wersji programu Access:
Access 2010 Odinstaluj aktualizację KB4484127
Access 2013 Odinstaluj aktualizację KB4484119
Access 2016 Odinstaluj aktualizację KB4484113
Access 2019 JEŚLI WYMAGANE (do potwierdzenia). Przejście z wersji 1808 (kompilacja 10352.20042) do wersji 1808 (kompilacja 10351.20054)
Office 365 ProPlus Przejście z wersji 1910 (kompilacja 12130.20344) na poprzednią kompilację, patrz https://support.microsoft.com/en-gb/help/2770432/ jak-przywrócić-do-wcześniejszej wersji-pakietu-2013-lub-pakietu-2016-clic
źródło
My i nasi klienci zmagaliśmy się z tym przez ostatnie dwa dni i ostatecznie napisaliśmy artykuł, aby szczegółowo omówić problem wraz z niektórymi rozwiązaniami: http://fmsinc.com/MicrosoftAccess/Errors/query_is_corrupt/
Zawiera nasze ustalenia, że wpływa to na rozwiązania Access podczas uruchamiania zapytań o aktualizację na lokalnych tabelach, połączonych tabelach dostępu, a nawet połączonych tabelach SQL Server.
Wpływa także na rozwiązania inne niż Microsoft Access, korzystające z Access Database Engine (ACE) w celu łączenia się z bazami danych Access za pomocą ADO. Obejmuje to aplikacje Visual Studio (WinForm), aplikacje VB6, a nawet strony internetowe, które aktualizują bazy danych Access na komputerach, na których nigdy nie zainstalowano Access lub Office.
Ta awaria może nawet wpłynąć na aplikacje Microsoft korzystające z ACE, takie jak PowerBI, Power Query, SSMA itp. (Niepotwierdzone), i oczywiście inne programy, takie jak Excel, PowerPoint lub Word, używające VBA do modyfikowania baz danych Access.
Oprócz oczywistej dezinstalacji szkodliwych Aktualizacji Bezpieczeństwa, uwzględniamy również niektóre opcje, gdy nie można odinstalować z powodu uprawnień lub dystrybucji aplikacji Access do zewnętrznych klientów, których komputery są poza Twoją kontrolą. Obejmuje to zmianę wszystkich zapytań o aktualizację i dystrybucję aplikacji Access za pomocą Access 2007 (sprzedaż detaliczna lub środowisko wykonawcze), ponieważ aktualizacje zabezpieczeń nie mają wpływu na tę wersję.
źródło
Skorzystaj z następującego modułu, aby automatycznie wdrożyć obejście sugerowane przez Mikrofty (używając zapytania zamiast tabeli). W ramach ostrożności najpierw wykonaj kopię zapasową bazy danych.
Użyj,
AddWorkaroundForCorruptedQueryIssue()
aby dodać obejście iRemoveWorkaroundForCorruptedQueryIssue()
usunąć je w dowolnym momencie.Najnowszy kod można znaleźć w moim repozytorium GitHub .
AddWorkaroundForCorruptedQueryIssue()
doda sufiks_Table
do wszystkich tabel niesystemowych, np.IceCreams
nazwa tabeli zostanie zmieniona naIceCreams_Table
.Stworzy również nowe zapytanie przy użyciu oryginalnej nazwy tabeli, która wybierze wszystkie kolumny tabeli o zmienionej nazwie. W naszym przykładzie zapytanie zostanie nazwane
IceCreams
i wykona SQLselect * from [IceCreams_Table]
.RemoveWorkaroundForCorruptedQueryIssue()
robi odwrotne działania.Przetestowałem to na wszystkich rodzajach tabel, w tym na zewnętrznych tabelach innych niż MDB (takich jak SQL Server). Należy jednak pamiętać, że użycie zapytania zamiast tabeli może prowadzić do wykonania niezoptymalizowanych zapytań w bazie danych zaplecza w określonych przypadkach, szczególnie jeśli oryginalne zapytania, które korzystały z tabel, są niskiej jakości lub bardzo złożone.
(I oczywiście, w zależności od stylu kodowania, możliwe jest również uszkodzenie aplikacji. Po sprawdzeniu, czy poprawka na ogół działa dla Ciebie, nigdy nie jest złym pomysłem, aby wyeksportować wszystkie obiekty jako tekst i użyć funkcji zastępowania znalezienia magia, aby upewnić się, że wszelkie wystąpienia użycia nazw tabel będą uruchamiane względem zapytań, a nie tabel).
W moim przypadku ta poprawka działa w dużej mierze bez żadnych skutków ubocznych, po prostu musiałem ręcznie zmienić nazwę z
USysRibbons_Table
powrotem naUSysRibbons
, ponieważ nie zaznaczyłem jej jako tabeli systemowej, kiedy ją tworzyłem w przeszłości.źródło
TableDef.Attributes
i kopiujesz ją do mojej odpowiedzi;) funkcja cofania jest dobrym pomysłem (ale stara i nowa nazwa powinna być przechowywana w tabeli, ponieważ zależy od braku tabel z sufiksem przed zmianą nazwy). Niektóre inne części są wadliwe (np. Tabele mogą kończyć się sufiksem lub nowa nazwa jest już w użyciu lubOn Error Resume Next
bez późniejszych błędów obsługi). Czy znasz RubberduckVBA ? Ten dodatek może sprawdzać twój kod i zawiera fajne sugestie dotyczące ulepszeń, oprócz wszystkich innych funkcji.Dla tych, którzy chcą zautomatyzować ten proces za pomocą PowerShell , oto kilka linków, które mogą być pomocne:
Wykryj i usuń obraźliwe aktualizacje
Dostępny jest tutaj skrypt PowerShell https://www.arcath.net/2017/09/office-update-remover, który wyszukuje w rejestrze określoną aktualizację pakietu Office (przekazaną jako numer KB) i usuwa ją za pomocą wywołania
msiexec.exe
. Ten skrypt analizuje oba identyfikatory GUID z kluczy rejestru, aby zbudować polecenie usunięcia odpowiedniej aktualizacji.Jedną zmianą, którą zasugerowałbym, byłoby użycie metody
/REBOOT=REALLYSUPPRESS
opisanej w Jak odinstalować KB4011626 i innych aktualizacji pakietu Office (dodatkowe informacje: https://docs.microsoft.com/en-us/windows/win32/msi/uninstalling-patches ). Linia poleceń, którą budujesz, wygląda następująco:Polecenie uruchomienia skryptu wyglądałoby mniej więcej tak:
Zapobiegaj instalowaniu aktualizacji
Zalecanym podejściem wydaje się tutaj ukrywanie aktualizacji . Oczywiście można to zrobić ręcznie, ale istnieją pewne skrypty PowerShell, które mogą pomóc w automatyzacji. Ten link: https://www.maketecheasier.com/hide-updates-in-windows-10/ szczegółowo opisuje ten proces, ale streszczę go tutaj.
Użyj następującego polecenia, aby ukryć aktualizację według numeru KB:
Hide-WUUpdate -KBArticleID KB4484127
Mam nadzieję, że będzie to pomocne dla kogoś innego.
źródło
Skrypt VBA dla obejścia MS:
Zaleca się usunięcie błędnej aktualizacji, jeśli to możliwe (jeśli nie, wypróbuj mój kod), przynajmniej dla wersji MSI. Zobacz odpowiedź https://stackoverflow.com/a/58833831/9439330 .
W przypadku wersji CTR (kliknij, aby uruchomić) musisz usunąć wszystkie listopadowe aktualizacje pakietu Office, co może powodować poważne problemy z bezpieczeństwem (nie jestem pewien, czy zostaną usunięte krytyczne poprawki).
Z komentarzy @ Erica:
Table.Tablename
do wiązania formularzy, stają się one niezwiązane, ponieważ poprzednia nazwa tabeli jest teraz nazwą zapytania !.OpenRecordSet(FormerTableNowAQuery, dbOpenTable)
zawiedzie (ponieważ jest to teraz zapytanie, a nie tabela)Uwaga! Wystarczy szybko przetestować w stosunku do Northwind.accdb na Office 2013 x86 CTR Brak gwarancji!
Dla testów:
źródło
Inventory to reorder Subform for Home
doInventory
stołu wHome
formie, bez problemów. Nawet nie zaleca się łączenia formularzy z zapytaniami zamiast z tabelami (czy nie wiąże się z tabelami jakSelect * From table
?).Table.TableName
notacji. Jeśli to zrobiszSELECT * FROM TableName
, to oczywiście w porządku. Ale jeśli użyjeszTable.TableName
, podformularz stanie się niezwiązany, jeśli zmienisz nazwę tabeli.TableDefs!MyTableName.OpenRecordset(dbOpenTable)
(obsługa wyszukiwania indeksów), z której również zwykle korzystam i również spowoduje błędy w twoim podejściuWymieniłem
currentDb.Execute
iDocmd.RunSQL
z funkcji pomocnika. Może to wstępnie przetworzyć i zmienić instrukcję SQL, jeśli jakakolwiek instrukcja aktualizacji zawiera tylko jedną tabelę. Mam jużdual
tabelę (pojedynczy wiersz, jedna kolumna), więc wybrałem opcję fakeTable.Uwaga : nie spowoduje to zmiany obiektów zapytania. Pomoże to jedynie w wykonywaniu SQL przez 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.
To tylko koncepcja
(If it's a single table update modify the sql before execution)
. Dostosuj go do swoich potrzeb. Ta metoda nie tworzy zapytań zastępczych dla każdej tabeli (co może być najłatwiejszym sposobem, ale ma swoje wady, np. Problemy z wydajnością)+ Punkty: Możesz nadal używać tego pomocnika nawet po tym, jak MS naprawi błąd, nic to nie zmieni. W przypadku, gdy przyszłość przyniesie kolejny problem, jesteś gotowy na
pre-process
SQL w jednym miejscu. Nie zdecydowałem się na metodę odinstalowywania aktualizacji , ponieważ wymaga to dostępu administratora + zajmie to zbyt długo, aby wszyscy mieli dostęp do poprawnej wersji + nawet jeśli odinstalujesz, zasady grupy niektórych użytkowników końcowych ponownie instalują najnowszą aktualizację. Wróciłeś do tego samego problemu.Jeśli masz dostęp do kodu źródłowego
use this method
i jesteś w 100% pewien, że żaden użytkownik nie ma problemu.Teraz tylko CTRL+F
Wyszukiwania i zamiany
docmd.RunSQL
zhelper.Execute
Wyszukiwania i zamiany
[currentdb|dbengine|or your dbobject].execute
zhelper.execute
baw się dobrze!
źródło
Ok, będę tu również dzwonił, ponieważ pomimo tego, że ten błąd został naprawiony, ta poprawka musi się jeszcze wypełnić w różnych przedsiębiorstwach, w których użytkownicy końcowi mogą nie być w stanie zaktualizować (np. Mój pracodawca ...)
Oto moje obejście
DoCmd.RunSQL "UPDATE users SET uname= 'bob' WHERE usercode=1"
. Po prostu skomentuj obraźliwe zapytanie i wpisz poniższy kod.Nie mogę powiedzieć, że jest ładna, ale wykonuje zadanie.
źródło