web-dev-qa-db-fra.com

Modification des problèmes d’enregistrement dans Access/SQL (conflit d’écriture)

un problème est survenu après la migration d'une base de données SQL que j'ai utilisée vers un nouveau serveur. Désormais, lorsque vous essayez de modifier un enregistrement dans Access (formulaire ou table), il est indiqué: WRITE CONFLICT: This record has been changed by another user since you started editing it...

Y a-t-il des raisons non évidentes à cela? Il n'y a personne d'autre utilisant le serveur, j'ai désactivé tous les déclencheurs sur la table. Je viens de constater que cela a quelque chose à voir avec les valeurs NULL, car les enregistrements qui n'en contiennent aucune sont corrects, mais certaines lignes qui en contiennent ne le sont pas. Serait-ce à voir avec les index? Si cela est pertinent, j'ai récemment commencé à télécharger quotidiennement BULK, plutôt que de le faire un par un en utilisant INSERT INTO à partir d'Access.

26
aSystemOverload

Une des raisons peut être que l'enregistrement en question a été ouvert sous une forme que vous modifiez. Si vous modifiez l'enregistrement par programme au cours de votre session d'édition, puis essayez de fermer le formulaire (et tentez ainsi de sauvegarder l'enregistrement), accès indique que l'enregistrement a été modifié par quelqu'un d'autre. 

Enregistrez le formulaire avant de modifier l'enregistrement par programme.
Sous la forme:

'This saves the form's current record
Me.Dirty = False

'Now, make changes to the record programmatically

UPDATE 1

Assurez-vous que la table SQL-Server a une clé primaire ainsi qu'une colonne d'horodatage.

La colonne timestamp aide Access à déterminer si l'enregistrement a été modifié depuis sa dernière sélection. Pour ce faire, Access inspecte tous les champs si aucun horodatage n'est disponible. Peut-être que cela ne fonctionne pas bien avec des entrées NULL s'il n'y a pas de colonne timestamp (voir ma mise à jour 2).

L'horodatage stocke en fait un numéro de version de ligne et non une heure.

N'oubliez pas d'actualiser le lien de table dans access après avoir ajouté une colonne d'horodatage, sinon Access ne la verra pas. (Remarque: L'Usizing Wizard de Microsoft crée des colonnes d'horodatage lors de la conversion de tables Access en tables SQL-Server.)


UPDATE 2

Selon @ AlbertD.Kallal, il pourrait s'agir d'un problème de bits nuls décrit ici: KB280730 . Si vous utilisez des champs de bits, définissez leur valeur par défaut sur 0 et remplacez les valeurs NULL entrées auparavant par 0. J'utilise habituellement un BIT DEFAULT 0 NOT NULL pour les champs booléens car il correspond le mieux à l'idée d'un booléen.

L'article de la base de connaissances dit d'utiliser un * .adp au lieu d'un * .mdb; Toutefois, Microsoft a cessé de prendre en charge Access Data Projects (ADP) dans Access 2013 .

40

Avait ce problème, même que l'affiche originale. Même en édition directe, sans formulaire. Le problème concerne les champs de bits. Si votre champ est Null, il convertit Null en 0 lorsque vous accédez à l’enregistrement, puis vous apportez des modifications qui sont cette fois la deuxième. Donc, les 2 changements de conflits. J'ai suivi la suggestion d'Olivier:

"Assurez-vous que la table a une clé primaire ainsi qu’une colonne horodatage ."

Et cela a résolu le problème.

11
BratPAQ

J'ai vu une situation similaire avec MS Access 2003 (et avant) lorsque lié à MS SQL Server 2000 (et avant). Dans mon cas, le problème concerne les champs de bits dans les tables de base de données MS SQL Server. Les champs de bits n'autorisent pas les valeurs NULL. Lorsque j'ajoutais un enregistrement à une table liée via MS Access 2003, la fenêtre de la base de données était renvoyée à une erreur, à moins que je ne définisse spécifiquement le champ de bits sur True ou False. Pour remédier à cette situation, j'ai modifié toutes les tables de données MS SQL Server afin que chaque champ de bits soit défini par défaut sur 0 ou 1. Une fois terminé, j'ai pu ajouter/modifier des données à la table liée via MS Access.

3
Spring

J'ai trouvé le problème en raison du conflit entre les champs de bits Jet/Access boolean et SQL Server.

Décrit ici sous le piège # 4 https://blogs.office.com/2012/02/17/five-common-pitfalls-when-upgrading-access-to-sql-server/

J'ai écrit un script SQL pour modifier tous les champs de bits en NOT NULL et fournir un défaut - zéro dans mon cas.

Exécutez cette opération dans SQL Server Management Studio, collez les résultats dans une nouvelle fenêtre de requête et exécutez-les; il est inutile de les placer dans un curseur et de les exécuter.

SELECT
    'UPDATE [' + o.name + '] SET [' + c.name + '] = ISNULL([' + c.name + '], 0);' + 
    'ALTER TABLE [' + o.name + '] ALTER COLUMN [' + c.name + '] BIT NOT NULL;' + 
    'ALTER TABLE [' + o.name + '] ADD  CONSTRAINT [DF_' + o.name + '_' + c.name + '] DEFAULT ((0)) FOR [' + c.name + ']'
FROM
    sys.columns c
INNER JOIN sys.objects o
ON  o.object_id = c.object_id
WHERE
    c.system_type_id = 104
    AND o.is_ms_shipped = 0;
2
user607237

C'est un bug avec Microsoft

Pour contourner ce problème, appliquez l'une des méthodes suivantes:

  • Mettez à jour le formulaire basé sur la vue multi-tables Sur la première occurrence du message d'erreur mentionné dans la section "Symptômes", vous devez cliquer sur Copier dans le Presse-papiers ou sur Supprimer les modifications dans la boîte de dialogue Conflit d'écriture. Pour éviter l'occurrence répétée du message d'erreur mentionné dans les "Symptômes"
    section, vous devez mettre à jour le jeu d’enregistrements du formulaire avant de le modifier.
    le même enregistrement à nouveau . Remarques Pour mettre à jour le formulaire dans Access 2003 ou Access 2002, cliquez sur Actualiser dans le menu Enregistrements . Pour mettre à jour le formulaire dans Access 2007, cliquez sur Actualiser tout dans le groupe Enregistrements sous l'onglet Accueil.

  • Utilisez un formulaire principal avec un sous-formulaire lié Pour éviter l'occurrence répétée du message d'erreur mentionné dans la section "Symptômes", vous pouvez utiliser un formulaire principal avec un
    sous-formulaire lié pour entrer des données dans les tables associées. Vous pouvez entrer
    enregistre dans les deux tables à partir d’un seul emplacement sans utiliser de formulaire basé sur la vue multi-tables . Pour créer un formulaire principal avec un sous-formulaire lié, procédez comme suit:

    Créez un nouveau formulaire basé sur la table (enfant) associée utilisée dans la vue multi-tables. Inclure les champs obligatoires Sur le formulaire . Enregistrez le formulaire, puis fermez le formulaire . Créez un nouveau formulaire basé sur la table primaire utilisée dans la vue multi-tables. Inclure les champs obligatoires sur le
    forme. Dans la fenêtre Base de données, ajoutez le formulaire que vous avez enregistré à l'étape 2 au formulaire principal.

    Cela crée un sous-formulaire . Définissez la propriété Link Child Fields et la propriété Link Master Fields du sous-formulaire sur le nom du ou des champs
    utilisé pour relier les tables.

Méthodes de contournement tirées de Support technique Microsoft

1
Hip Hip Array

J'ai rencontré les deux causes détaillées ci-dessus: Modification directe des données dans une table actuellement liée à un formulaire ET ayant un champ de type "bit" dans SQL Server pour lequel la valeur par défaut n'est pas définie sur "0" (zéro).

La seule façon pour moi de contourner ce dernier problème consiste à ajouter la valeur par défaut de zéro au champ de bits ET à exécuter une requête de mise à jour pour définir toutes les valeurs actuelles à zéro.

Afin de contourner l'erreur précédente, j'ai dû faire preuve d'inventivité. Parfois, je peux modifier l'ordre des instructions VBA et déplacer Refresh ou Requery vers un emplacement différent, évitant ainsi le message d'erreur. Dans la plupart des cas, cependant, ce que je fais est DIM une variable de chaîne dans le sous-programme où j'appelle la mise à jour directe de table. AVANT que j'appelle la mise à jour, j'ai défini cette variable String sur la valeur de Recordsource derrière le formulaire lié, capturant ainsi la déclaration SQL exacte utilisée à ce moment-là. Ensuite, j'ai défini Recordsource du formulaire sur une chaîne vide ("") afin de le déconnecter des données. Ensuite, j'effectue la mise à jour des données. Ensuite, j'ai redéfini Recordsource du formulaire sur la valeur enregistrée dans la variable String, en rétablissant la liaison et en lui permettant de récupérer la ou les nouvelles valeurs de la table. Si un ou plusieurs sous-formulaires sont contenus dans ce formulaire, les champs "Lien" doivent être traités de la même manière que Recordsource. Lorsque Recordsource est défini sur une chaîne vide, vous pouvez voir #Name dans les champs désormais non liés. Ce que je fais est simplement de définir la propriété Visible sur False au plus haut niveau possible (section Détail, sous-formulaire, etc.) pendant le temps où Recordsource est vide, masquant les valeurs #Name à l'utilisateur. Définir Recordsource sur une chaîne vide est ma solution idéale lorsqu'un changement de codage est introuvable. Je me demande cependant si mes compétences en conception font défaut et s'il existe un moyen d'éviter complètement le problème.

Une dernière pensée sur l’adressage du message d’erreur: au lieu d’appeler une routine pour mettre à jour directement les données de la table, je trouve un moyen de mettre à jour les données via le formulaire, en ajoutant un contrôle lié au formulaire et en mettant à jour les données dans afin que les données de formulaire et les données de table ne deviennent pas désynchronisées.

1
KWells

Si vous utilisez des tables liées, assurez-vous de les avoir mises à jour et réessayez avant de faire quoi que ce soit.

Je pensais que je les avais mis à jour mais que personne ne mettait à jour la charte et les tables SQL pour permettre 150 caractères, mais que la table liée n'avait pas été rafraîchie.

Pas sûr que ce soit l'erreur la plus appropriée pour le scénario, mais bon, la plupart des problèmes intéressants ne sont jamais signalés correctement dans aucun logiciel Microsoft!

0
greeny129

J'ai traité ce problème avec des tables MS Access liées à des tables MS SQL à plusieurs reprises. La réponse de l'affiche originale a été extrêmement utile et a été à l'origine de la plupart de mes problèmes.

J'ai également rencontré ce problème quand j'ai accidentellement ajouté un champ de bits avec un espace dans le nom du champ ... ouais ...

J'avais exécuté alter table tablename add [nom du champ] bit 0 par défaut. La solution que j'ai trouvée consistait à supprimer ce champ sans laisser d'espace dans le nom.

0
Ben Reisner

Je venais tout juste d’avoir des problèmes de conflit d’écriture très graves (Acc2013 32 bits, SQL Srv2017 expr) avec un Split-Form plutôt "lourdement chargé" . simplement

Configurez la feuille de données AcSplitForm sur READ-ONLY !!! (Je ne sais pas pourquoi il était en lecture-écriture, de toute façon, je dois l'avoir réglé par défaut ...)

Cela m'a presque coûté une semaine entière pour le découvrir. 

0
Klaus Oberdalhoff

Afin de surmonter ce problème. J'ai créé VBA pour changer un autre champ dans la même ligne. J'ai donc créé un champ séparé qui ajoute 1 au contenu lorsque j'essaie de fermer le formulaire. Cela a résolu le problème.

0
Stuart

J'avais ce problème et j'ai réalisé que c'était en ajoutant un nouveau champ de bits à une table existante. J'ai supprimé le nouveau champ et tout est rentré dans l'ordre.

0
Alicia

J'utilise cette solution de contournement et cela a fonctionné pour moi: Front-end: MS Access Backend: Mysql

Sur l'événement Avant la mise à jour d'un champ donné:

Private Sub tbl_comuna_id_comuna_BeforeUpdate(Cancel As Integer)

If Me.tbl_comuna_id_comuna.OldValue = Me.tbl_comuna_id_comuna.Value Then
Cancel = True
Undo
End If
End Sub
0
pperez