web-dev-qa-db-fra.com

L'opération doit utiliser une requête pouvant être mise à jour. (Erreur 3073) Microsoft Access

Sur certaines requêtes Microsoft Access, je reçois le message suivant: Operation doit utiliser une requête pouvant être mise à jour. (Erreur 3073). Je travaille autour de cela en utilisant des tables temporaires, mais je me demande s'il existe un meilleur moyen. Toutes les tables impliquées ont une clé primaire. Voici le code:

UPDATE CLOG SET CLOG.NEXTDUE = (
    SELECT H1.paidthru 
    FROM CTRHIST as H1
    WHERE H1.ACCT = clog.ACCT AND
    H1.SEQNO = (
        SELECT MAX(SEQNO) 
        FROM CTRHIST 
        WHERE CTRHIST.ACCT = Clog.ACCT AND 
        CTRHIST.AMTPAID > 0 AND
        CTRHIST.DATEPAID < CLOG.UPDATED_ON
    )
)
WHERE CLOG.NEXTDUE IS NULL;
21
Knox

Depuis Jet 4, toutes les requêtes ayant une jointure à une instruction SQL qui résume les données ne pourront pas être mises à jour. Vous n'utilisez pas JOIN, mais la clause WHERE est exactement équivalente à une jointure et, par conséquent, l'optimiseur de requête Jet la traite de la même manière qu'il traite une jointure.

Je crains fort que vous n'ayez pas de chance sans table temporaire, bien que quelqu'un avec une connaissance plus approfondie de Jet SQL que je puisse trouver une solution de contournement.

En passant, il a peut-être été mis à jour dans Jet 3.5 (Access 97), car de nombreuses requêtes pouvaient être mises à jour puis devenues non-modifiables lors de la mise à niveau vers Jet 4.


23
David-W-Fenton

J'ai eu un problème similaire où les requêtes suivantes ne fonctionnaient pas;

update tbl_Lot_Valuation_Details as LVD
set LVD.LGAName = (select LGA.LGA_NAME from tbl_Prop_LGA as LGA where LGA.LGA_CODE = LVD.LGCode)
where LVD.LGAName is null;

update tbl_LOT_VALUATION_DETAILS inner join tbl_prop_LGA on tbl_LOT_VALUATION_DETAILS.LGCode = tbl_prop_LGA.LGA_CODE 
set tbl_LOT_VALUATION_DETAILS.LGAName = [tbl_Prop_LGA].[LGA_NAME]
where tbl_LOT_VALUATION_DETAILS.LGAName is null;

Cependant, l'utilisation de DLookup a résolu le problème.

update tbl_Lot_Valuation_Details as LVD
set LVD.LGAName = dlookup("LGA_NAME", "tbl_Prop_LGA", "LGA_CODE="+LVD.LGCode)
where LVD.LGAName is null;

Cette solution avait été proposée initialement à https://stackoverflow.com/questions/537161/sql-update-woes-in-ms-access-operation-must-use-an-updatable-query

7
Ray Brack

Il n'y a pas d'erreur dans le code. Mais l'erreur est renvoyée pour la raison suivante.

 - Please check weather you have given Read-write permission to MS-Access database file.

 - The Database file where it is stored (say in Folder1) is read-only..? 

supposons que la base de données (fichier MS-Access) soit stockée dans un dossier en lecture seule. Lors de l'exécution de votre application, la connexion n'est pas forcée. Par conséquent, changez l’autorisation de fichier/l’autorisation de dossier qui la contient, comme dans C:\Program files, la plupart des fichiers de lecteur c ayant été définis en lecture seule , de sorte que la modification de cette autorisation résout ce problème.

4

Le problème est lié à l’utilisation de (dans ce cas) la fonction max (). Toute fonction d'agrégation utilisée lors d'une jointure (par exemple, pour récupérer la valeur maximale ou minimale ou la valeur moyenne d'une table jointe) entraînera l'erreur. Et la même chose s'applique à l'utilisation de sous-requêtes au lieu de jointures (comme dans le code d'origine).

C'est incroyablement ennuyeux (et injustifié!) Car il est assez courant de vouloir faire cela. J'ai également dû utiliser des tables temporaires pour contourner le problème (extraire la valeur agrégée dans une table temporaire avec une instruction insert, puis rejoindre cette table avec votre mise à jour, puis supprimer la table temporaire).

Glenn

4
Glenn M

Je sais que ma réponse a 7 ans de retard, mais voici ma suggestion quand même: 

Lorsque Access se plaint d'une requête UPDATE qui inclut une JOIN, il suffit d'enregistrer la requête avec la propriété RecordsetType définie sur Dynaset (Inconsistent Updates)

Cela permettra parfois à UPDATE de fonctionner.

3
Patrick Honorez

Cela se produit lorsqu'il n'y a pas de clé UNIQUE MS-ACCESS pour la ou les tables mises à jour. (Quel que soit le schéma SQL).

Lors de la création de liens MS-Access vers des tables SQL, vous êtes invité à spécifier l'index (clé) au moment de la liaison. Si cela est fait incorrectement ou pas du tout, la requête sur la table liée ne peut pas être mise à jour.

Lorsque vous liez des tables SQL à Access, ASSUREZ-VOUS QUE, lorsque Access vous invite à indiquer l'index (clé), vous utilisez exactement ce que SQL utilise pour éviter les problèmes, bien que la spécification d'une clé unique soit tout ce dont Access a besoin pour mettre à jour la table.

Si vous n'étiez pas la personne qui a lié la table à l'origine, supprimez la table liée de MS-ACCESS (le lien est uniquement supprimé) et reliez-la en spécifiant la clé correctement et tout fonctionnera correctement.

2
Dave Nilson

J'essayerais de construire la requête UPDATE dans Access. J'ai eu une requête UPDATE que j'ai moi-même écrite comme

UPDATE TABLE1
SET Field1 = 
(SELECT Table2.Field2
 FROM Table2
 WHERE Table2.UniqueIDColumn = Table1.UniqueIDColumn)

La requête m'a donné cette erreur que vous voyez. Cela a cependant fonctionné sur mon serveur SQL, mais comme les réponses précédentes, la syntaxe Access UPDATE n'est pas la syntaxe standard. Cependant, lorsque je l'ai reconstruit à l'aide de l'assistant de requête d'Access (il utilisait la syntaxe JOIN), tout fonctionnait bien. Normalement, je faisais simplement passer la requête UPDATE à la syntaxe non-JET, mais l'une des tables à laquelle je rejoignais était une table Access locale.

2
StoneJedi

(Un peu tard pour la fête ...)

Les trois manières dont je me suis occupé de ce problème par le passé sont les suivantes:

  1. Référence une zone de texte sur un formulaire ouvert
  2. DSum
  3. DLookup
1
mark

Le mien a échoué avec une simple instruction INSERT. Fixé en démarrant l'application avec 'Exécuter en tant qu'administrateur' access.

1
nspire

J'ai eu le même problème.

Ma solution consiste d'abord à créer une table à partir de la requête non modifiable, puis à effectuer la mise à jour de table en table et tout fonctionne.

1
marcnz

MS Access - joindre des tables dans une requête de mise à jour ... comment la mettre à jour

  1. Ouvrir la requête en mode Création
  2. Cliquez une fois sur le lien b/w tables/view
  3. Dans la fenêtre «Propriétés», remplacez la valeur «oui» par «enregistrements uniques».
  4. Enregistrez la requête en tant que requête de mise à jour et exécutez-la.
1
Paul Dungan

Je continuais à avoir la même erreur, mais tous les SQL s'exécutent dans Access très bien.

et quand j'ai modifié le permission de AccessFile.

le problème résolu !!

Je donne ' Service réseau ' autorisation de contrôle total du compte, ce compte si pourIIS

0

Aujourd'hui, dans mon MS-Access 2003 avec un tabla ODBC pointant vers un serveur SQL Server 2000 avec un mot de passe sa m'a donné la même erreur.
J'ai défini une clé primaire sur la table de la base de données SQL Server et le problème a disparu.

0
Ariel Alvarez

La réponse donnée ci-dessus par iDevlop a fonctionné pour moi. Notez que je n'ai pas pu trouver la propriété RecordsetType dans ma requête de mise à jour. Cependant, j'ai pu trouver cette propriété en remplaçant ma requête par une requête de sélection, en définissant cette propriété comme indiqué par iDevlop, puis en remplaçant ma requête par une requête de mise à jour. Cela a fonctionné, pas besoin de table temporaire. 

J'aurais aimé que ce soit juste un commentaire sur ce que iDevlop a posté pour que cela découle de sa solution, mais je n'ai pas un score assez élevé.

0
Sue White

Il y a un autre scénario ici qui s'appliquerait. Un fichier qui a été extrait de Visual Source Safe, pour tous ceux qui l'utilisent encore, à qui n'a pas été attribué "Écriture", que ce soit dans l'option Afficher ou Check Out, recevra également ce message d'erreur.

La solution consiste à ré-acquérir le fichier à partir de Source Safe et à appliquer le paramètre d’écriture.

0
htm11h

Vous pouvez toujours écrire le code dans VBA qui met à jour de la même manière. J'ai eu ce problème aussi, et ma solution de contournement consistait à faire une requête select, avec toutes les jointures, qui contenait toutes les données que je cherchais pour pouvoir les mettre à jour, ce qui en faisait un jeu d'enregistrements et en lançant la requête de mise à jour à plusieurs reprises. seulement la table de mise à jour, recherchant uniquement les critères que vous recherchez 

    Dim updatingItems As Recordset
    Dim clientName As String
    Dim tableID As String
    Set updatingItems = CurrentDb.OpenRecordset("*insert SELECT SQL here*");", dbOpenDynaset)
    Do Until updatingItems .EOF
        clientName = updatingItems .Fields("strName")
        tableID = updatingItems .Fields("ID")
        DoCmd.RunSQL "UPDATE *ONLY TABLE TO UPDATE* SET *TABLE*.strClientName= '" & clientName & "' WHERE (((*TABLE*.ID)=" & tableID & "))"
        updatingItems.MoveNext
    Loop

Je ne fais cela que pour environ 60 enregistrements par jour, mais plusieurs milliers pourraient prendre beaucoup plus de temps, car la requête s'exécute du début à la fin à plusieurs reprises, au lieu de simplement sélectionner un groupe global et d'y apporter des modifications. Vous aurez peut-être besoin de '' autour des guillemets pour tableID, car c'est une chaîne, mais je suis à peu près sûr que c'est ce qui a fonctionné pour moi.

0
RSmith

Quand j'ai eu cette erreur, c'est peut-être parce que ma syntaxe UPDATE était fausse, mais après avoir corrigé la requête de mise à jour, j'ai eu à nouveau la même erreur ... alors je suis allé au ODBC Data Source Administrator et j'ai découvert que ma connexion était en lecture seule. Après avoir établi la connexion en lecture-écriture et re-connectée, cela a très bien fonctionné.

0
leeand00

vérifier votre base de données (permission de la base de données) et donner une permission complète

Allez dans le dossier DB-> cliquez avec le bouton droit sur propriétés-> sécurité-> édition-> donnez le contrôle total & Menu Démarrer -> Exécuter-> taper "uac" le réduire (s'il est trop haut)

0
Manoj essl

Pour répondre plus avant à ce que DRUA a mentionné dans sa réponse ...

Je développe mes bases de données dans Access 2007. Mes utilisateurs utilisent Access 2007 Runtime. Ils ont des autorisations de lecture sur un dossier database_Front (front end) et des autorisations de lecture/écriture sur le dossier database_Back. 

Lors du déploiement d'une nouvelle base de données, l'utilisateur n'a pas suivi les instructions complètes de la copie du serveur sur son ordinateur et a plutôt créé un raccourci. L'exécution du Front-end par le raccourci créera une condition dans laquelle la requête ne peut pas être mise à jour en raison des restrictions d'écriture de fichier. 

Copier le serveur dans son dossier de documents résout le problème. 

Oui, cela complique les choses lorsque les utilisateurs doivent obtenir une version mise à jour du serveur frontal, mais au moins, la requête fonctionne sans avoir à recourir à des tables temporaires. 

0

Je continuais à avoir la même erreur jusqu'à ce que je fasse du champ de connexion un index unique dans les deux tables de connexion. Ce n'est qu'alors que la requête est devenue modifiable.

Philip Stilianos

0
Philip Stilianos

En substance, alors que votre code SQL semble parfaitement raisonnable, Jet n’a jamais pris en charge la syntaxe standard SQL pour UPDATE. Au lieu de cela, il utilise sa propre syntaxe propriétaire (différente à nouveau de la syntaxe propriétaire UPDATE de SQL Server) qui est limitée à very. Souvent, les seules solutions de contournement "L'opération doit utiliser une requête pouvant être mise à jour" sont très pénibles. Envisagez sérieusement de passer à un produit SQL plus performant.

Pour plus de détails sur vos problèmes spécifiques et certaines solutions de contournement possibles, voir Requête de mise à jour en fonction de la requête de totalisation échoue .

0
onedaywhen