Sommaire
Il s'agit d'un bogue connu provoqué par les mises à jour d'Office publiées le 12 novembre 2019. Le bogue affecte toutes les versions d'Access actuellement prises en charge par Microsoft (d'Access 2010 à 365).
Ce bug a été corrigé.
- Si vous utilisez une version C2R (Click-to-Run) d'Office, utilisez "Mettre à jour maintenant" :
- Access 2010 C2R: corrigé dans la version 7243.5000
- Access 2013 C2R: corrigé dans la version 5197.1000
- Access 2016 C2R: corrigé dans la version 12130.20390
- Access 2019 (v1910): corrigé dans la version 12130.20390
- Access 2019 (licence en volume): corrigé dans la version 10353.20037
- Canal mensuel Office 365: résolu dans la version 12130.20390
- Office 365 semi-annuel: corrigé dans la version 11328.20480
- Office 365 semi-annuel étendu: corrigé dans la version 10730.20422
- Office 365 semi-annuel ciblé: corrigé dans la version 11929.20494
- Si vous utilisez une version MSI d'Office, installez la mise à jour correspondant à votre version d'Office. Tous ces correctifs ont été publiés sur Microsoft Update, donc l' installation de toutes les mises à jour Windows en attente devrait suffire:
Exemple
Voici un exemple de repro minimal:
- Créez une nouvelle base de données Access.
- Créez une nouvelle table vide "Table1" avec le champ ID par défaut et un champ entier long "myint".
Exécutez le code suivant dans la fenêtre immédiate de l'éditeur VBA:
CurrentDb.Execute "UPDATE Table1 SET myint = 1 WHERE myint = 1"
Résultat attendu : l'instruction se termine avec succès.
Résultat réel avec l'une des mises à jour de buggy installée: Une erreur d'exécution 3340 se produit ("La requête" est corrompue ").
Liens connexes:
90150000-006E-0409-0000-0000000FF1CE
... ce n'est-0409-
pas le cas-0407-
.-006E-0409-
également. Les deux machines ont le Service Pack 1 pour Microsoft Office 2013 (KB2850036) installé.{90140000-0011-0000-0000-0000000FF1CE}
dans le script de commandes. Notez{9014...
pas{9114..}
Solution la plus simple
Pour mes utilisateurs, attendre près d'un mois jusqu'au 10 décembre pour une version de correctif de Microsoft n'est pas une option. La désinstallation de la mise à jour Microsoft incriminée n'est pas non plus effectuée sur plusieurs postes de travail verrouillés par le gouvernement.
Je dois appliquer une solution de contournement, mais je ne suis pas exactement ravi de ce que Microsoft a suggéré - créer et remplacer une requête pour chaque table.
La solution consiste à remplacer le nom de la table par une simple
(SELECT * FROM Table)
requête directement dans laUPDATE
commande. Cela ne nécessite pas de créer et d'enregistrer une tonne de requêtes, de tables ou de fonctions supplémentaires.EXEMPLE:
Avant:
Après:
Cela devrait être beaucoup plus facile à implémenter sur plusieurs bases de données et applications (et restauration ultérieure).
la source
Ce n'est pas un problème de mise à jour Windows, mais un problème qui a été introduit avec la version de novembre du Patch Tuesday d'Office. Une modification apportée pour corriger une vulnérabilité de sécurité entraîne le signalement de certaines requêtes légitimes comme corrompues. Étant donné que le changement était un correctif de sécurité, il affecte TOUTES les versions d'Office, y compris 2010, 2013, 2016, 2019 et O365.
Le bug a été corrigé dans tous les canaux, mais le moment de la livraison dépendra du canal sur lequel vous vous trouvez.
Pour les versions MSI 2010, 2013 et 2016, et les licences en volume 2019 et le canal semi-annuel O365, le correctif sera dans la version du mardi de décembre, le 10 décembre. Pour O365, le canal mensuel et les initiés, cela sera corrigé lorsque la fourchette d'octobre sera publiée, actuellement prévue pour le 24 novembre.
Pour la chaîne semi-annuelle, le bogue a été introduit en 11328.20468, qui a été publié le 12 novembre, mais ne se déploie pas pour tout le monde à la fois. Si vous le pouvez, vous voudrez peut-être retarder la mise à jour jusqu'au 10 décembre.
Le problème se produit pour les requêtes de mise à jour sur une seule table avec un critère spécifié (de sorte que les autres types de requêtes ne doivent pas être affectés, ni aucune requête qui met à jour toutes les lignes d'une table, ni une requête qui met à jour le jeu de résultats d'une autre requête). Dans ce cas, la solution de contournement la plus simple consiste dans la plupart des cas à modifier la requête de mise à jour pour mettre à jour une autre requête qui sélectionne tout dans la table, plutôt que de mettre à jour la requête directement.
C'est à dire, si vous avez une requête comme:
Ensuite, créez une nouvelle requête (Query1) définie comme:
et mettez à jour votre requête d'origine pour:
Page officielle: Erreur d'accès: "La requête est corrompue"
la source
La résolution temporaire de ce problème dépend de la version d'Access utilisée:
Access 2010 Uninstall update KB4484127
Access 2013 Uninstall update KB4484119
Access 2016 Uninstall update KB4484113
Access 2019 IF REQUIRED (tbc). Rétrograder de la version 1808 (build 10352.20042) à la version 1808 (build 10351.20054)
Office 365 ProPlus Rétrograder de la version 1910 (build 12130.20344) à une build précédente, voir https://support.microsoft.com/en-gb/help/2770432/ comment-revenir-à-une-version-antérieure-de-office-2013-ou-office-2016-clic
la source
Nous et nos clients avons eu du mal avec cela au cours des deux derniers jours et avons finalement écrit un document pour discuter du problème en détail avec quelques solutions: http://fmsinc.com/MicrosoftAccess/Errors/query_is_corrupt/
Il inclut nos constatations selon lesquelles il a un impact sur les solutions Access lors de l'exécution de requêtes de mise à jour sur des tables locales, des tables Access liées et même des tables SQL Server liées.
Il affecte également les solutions non Microsoft Access utilisant le moteur de base de données Access (ACE) pour se connecter aux bases de données Access à l'aide d'ADO. Cela inclut les applications Visual Studio (WinForm), les applications VB6 et même les sites Web qui mettent à jour les bases de données Access sur des ordinateurs sur lesquels Access ou Office n'ont jamais été installés.
Ce plantage peut même avoir un impact sur les applications Microsoft qui utilisent ACE telles que PowerBI, Power Query, SSMA, etc. (non confirmé), et bien sûr, d'autres programmes tels qu'Excel, PowerPoint ou Word utilisant VBA pour modifier les bases de données Access.
En plus de la désinstallation évidente des mises à jour de sécurité incriminées, nous incluons également certaines options lorsqu'il n'est pas possible de désinstaller en raison d'autorisations ou de la distribution d'applications Access à des clients externes dont les PC sont hors de votre contrôle. Cela inclut la modification de toutes les requêtes de mise à jour et la distribution des applications Access à l'aide d'Access 2007 (vente au détail ou exécution), car cette version n'est pas affectée par les mises à jour de sécurité.
la source
Utilisez le module suivant pour implémenter automatiquement la solution de contournement suggérée par Microsofts (en utilisant une requête au lieu d'une table). Par mesure de précaution, sauvegardez d'abord votre base de données.
Utilisez
AddWorkaroundForCorruptedQueryIssue()
pour ajouter la solution de contournement etRemoveWorkaroundForCorruptedQueryIssue()
pour la supprimer à tout moment.Vous pouvez trouver le dernier code sur mon référentiel GitHub .
AddWorkaroundForCorruptedQueryIssue()
ajoutera le suffixe_Table
à toutes les tables non système, par exemple la tableIceCreams
sera renommée enIceCreams_Table
.Il créera également une nouvelle requête en utilisant le nom de la table d'origine, qui sélectionnera toutes les colonnes de la table renommée. Dans notre exemple, la requête serait nommée
IceCreams
et exécuterait le SQLselect * from [IceCreams_Table]
.RemoveWorkaroundForCorruptedQueryIssue()
fait les actions inverses.J'ai testé cela avec toutes sortes de tables, y compris des tables externes non MDB (comme SQL Server). Mais sachez que l'utilisation d'une requête au lieu d'une table peut entraîner l'exécution de requêtes non optimisées sur une base de données backend dans des cas spécifiques, surtout si vos requêtes d'origine qui ont utilisé les tables sont de mauvaise qualité ou très complexes.
(Et bien sûr, selon votre style de codage, il est également possible de casser des choses dans votre application. Donc, après avoir vérifié que le correctif fonctionne généralement pour vous, ce n'est jamais une mauvaise idée d'exporter tous vos objets sous forme de texte et d'utiliser certains find replace magique pour garantir que toutes les occurrences de noms de table seront exécutées sur les requêtes et non sur les tables.)
Dans mon cas, ce correctif fonctionne en grande partie sans aucun effet secondaire, je devais juste renommer manuellement
USysRibbons_Table
revenir àUSysRibbons
, comme je ne l' avais pas marqué comme une table système lorsque je l' ai créé dans le passé.la source
TableDef.Attributes
et copiez cela dans ma réponse;) et une fonction d'annulation est une bonne idée (mais l'ancien et le nouveau nom doivent être stockés dans une table car ne dépendant d'aucune table avec suffixe avant le renommage). Certaines autres parties sont défectueuses (par exemple, les tables peuvent se terminer par le suffixe ou le nouveau nom est déjà utilisé ouOn Error Resume Next
sans gérer les erreurs plus tard). Connaissez-vous RubberduckVBA ? Cet add-in peut inspecter votre code et fait de belles suggestions d'amélioration, en plus de toutes les autres fonctionnalités.Pour ceux qui cherchent à automatiser ce processus via PowerShell , voici quelques liens que j'ai trouvés qui peuvent être utiles:
Détecter et supprimer les mises à jour incriminées
Un script PowerShell est disponible ici https://www.arcath.net/2017/09/office-update-remover qui recherche dans le registre une mise à jour Office spécifique (transmise sous forme de numéro de ko) et la supprime à l'aide d'un appel à
msiexec.exe
. Ce script analyse les deux GUID des clés de registre pour générer la commande de suppression de la mise à jour appropriée.Une modification que je suggérerais serait d'utiliser le
/REBOOT=REALLYSUPPRESS
comme décrit dans Comment désinstaller KB4011626 et d'autres mises à jour Office (référence supplémentaire: https://docs.microsoft.com/en-us/windows/win32/msi/uninstalling-patches ). La ligne de commande que vous créez ressemble à ceci:La commande pour exécuter le script ressemblerait à ceci:
Empêcher l'installation des mises à jour
L'approche recommandée ici semble masquer la mise à jour . Évidemment, cela peut être fait manuellement, mais certains scripts PowerShell peuvent aider à l'automatisation. Ce lien: https://www.maketecheasier.com/hide-updates-in-windows-10/ décrit le processus en détail, mais je vais le résumer ici.
Utilisez la commande suivante pour masquer une mise à jour par numéro de Ko:
Hide-WUUpdate -KBArticleID KB4484127
J'espère que cela sera utile à quelqu'un d'autre.
la source
VBA-Script pour MS-contournement:
Il est recommandé de supprimer la mise à jour du buggy, si possible (sinon essayez mon code), au moins pour les versions MSI. Voir la réponse https://stackoverflow.com/a/58833831/9439330 .
Pour les versions CTR (Click-To-Run), vous devez supprimer toutes les mises à jour Office de novembre, ce qui peut entraîner de graves problèmes de sécurité (vous ne savez pas si des correctifs critiques seront supprimés).
D'après les commentaires de @ Eric:
Table.Tablename
pour lier des formulaires, ils deviennent non liés car l'ancien nom de table est maintenant un nom de requête !.OpenRecordSet(FormerTableNowAQuery, dbOpenTable)
échouera (car c'est une requête maintenant, plus une table)Mise en garde! Test rapide contre Northwind.accdb sur Office 2013 x86 CTR Aucune garantie!
Pour tester:
la source
Inventory to reorder Subform for Home
à laInventory
table sousHome
forme, sans problème. Même n'est-il pas recommandé de lier des formulaires à des requêtes au lieu de tables (n'est-ce pas une liaison à une table commeSelect * From table
?).Table.TableName
notation. Si vous le faites à laSELECT * FROM TableName
place, vous êtes bien sûr bien. Mais si vous utilisezTable.TableName
, votre sous-formulaire deviendra indépendant si vous renommez la table.TableDefs!MyTableName.OpenRecordset(dbOpenTable)
(support de la recherche d'index), que j'ai également tendance à utiliser et qui causera également des erreurs avec votre approcheJ'ai remplacé le
currentDb.Execute
etDocmd.RunSQL
par une fonction d'aide. Cela peut prétraiter et modifier l'instruction SQL si une instruction de mise à jour contient une seule table. J'ai déjà unedual
table ( une seule ligne, une seule colonne), donc je suis allé avec une option fakeTable.Remarque : cela ne changera pas vos objets de requête. Il n'aidera que les exécutions SQL via 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.
Ce n'est qu'un concept
(If it's a single table update modify the sql before execution)
. Adaptez-le selon vos besoins. Cette méthode ne crée pas de requêtes de remplacement pour chaque table (ce qui peut être le moyen le plus simple mais a ses propres inconvénients. Par exemple, les problèmes de performances)+ Points: Vous pouvez continuer à utiliser cet assistant même après que MS a corrigé le bug, cela ne changera rien. Dans le cas où l'avenir apporte un autre problème, vous êtes prêt à
pre-process
votre SQL en un seul endroit. Je n'ai pas opté pour la méthode de désinstallation des mises à jour car cela nécessite un accès administrateur + ça va prendre trop de temps pour obtenir tout le monde sur la bonne version + même si vous désinstallez, la stratégie de groupe de certains utilisateurs finaux réinstalle la dernière mise à jour. Vous revenez au même problème.Si vous avez accès au code source
use this method
et que vous êtes sûr à 100% qu'aucun utilisateur final ne rencontre le problème.Maintenant juste CTRL+F
Rechercher et remplacer
docmd.RunSQL
parhelper.Execute
Rechercher et remplacer
[currentdb|dbengine|or your dbobject].execute
parhelper.execute
s'amuser!
la source
Ok je vais carillon ici aussi, car même si ce bogue a été corrigé, ce correctif n'a pas encore été entièrement rempli par diverses entreprises où les utilisateurs finaux peuvent ne pas être en mesure de mettre à jour (comme mon employeur ...)
Voici ma solution de contournement
DoCmd.RunSQL "UPDATE users SET uname= 'bob' WHERE usercode=1"
. Il suffit de commenter la requête incriminée et de déposer le code ci-dessous.Je ne peux pas dire que c'est joli, mais ça fait le travail.
la source