Question L'accès passe parfois à l'enregistrement existant sur save new record - Access2k FE / SQL2005 BE


Je suis vraiment en train de poster ce désespoir après avoir beaucoup cherché une réponse et essayé différentes choses sans succès.

J'ai une base de données Access où j'ai récemment migré les tables vers SQL 2005, Access continue à fonctionner pour les utilisateurs en tant que serveur frontal fournissant des formulaires, des rapports et des requêtes.

Cependant, depuis le passage à l'installation FE / SQL BE Access, les utilisateurs ont signalé que parfois, lorsqu'ils saisissent un nouvel enregistrement, cliquent sur un sous-formulaire (en enregistrant l'enregistrement) ou cliquent sur Enregistrer dans le menu lui-même, il accède à un enregistrement existant. Le nouvel enregistrement a été enregistré, mais pour une raison quelconque, l’accès à un autre enregistrement est actualisé. L'utilisateur doit ensuite fermer, rechercher l'enregistrement enregistré et continuer à le modifier.

Scénario: Un utilisateur entre un devis et remplit tous les détails du devis, client,   date, etc, puis clique dans le sous-formulaire des éléments de ligne pour ajouter un produit (ou cliquez sur enregistrer dans le menu), et soudainement   le formulaire de devis (et le sous-formulaire d'élément de ligne) affiche les détails d'un devis aléatoire. La citation aléatoire pourrait être récente ou datant de plusieurs années, et n’a rien à voir avec la citation qu’ils entraient.

Ce comportement étrange se produit uniquement lors de l'insertion d'un nouvel enregistrement, jamais lors de l'édition d'un enregistrement existant. Les utilisateurs me disent que cela arrive 'plus souvent'quand ils vont ajouter un nouveau (devis, client, peu importe) après l'ouverture de la base de données.

J'ai remarqué que cela ne se produisait que sur des formulaires dotés de sous-formulaires. Ma première pensée est que cela concernait l'accès à Access via les données du sous-formulaire avant que les données du formulaire ne soient enregistrées, provoquant une violation PK. Mais cela ne semble pas se produire: il n'y a pas d'erreurs sur le serveur SQL et l'enregistrement est correctement enregistré. Le fait de forcer les utilisateurs à enregistrer l’enregistrement de formulaire principal avant d’ajouter des enregistrements de sous-formulaire (c’est-à-dire sur un devis, les obligeant à enregistrer le devis avant de pouvoir ajouter des éléments de campagne) n’a pas fonctionné.

Ce n'est pas vba qui s'exécute sur la sauvegarde ou sur le courant, j'ai défini des points d'arrêt sur tous les gestionnaires d'événements pendant qu'ils sautent et aucun vba n'est en cours d'exécution. Certaines des formes «sautantes» n'ont pas de vba sur la forme. Mais tous ont des sous-formulaires. Je pense que cela a à voir avec le verrouillage des enregistrements.

Le serveur exécutant les tables est SQL Server 2005, les utilisateurs utilisent un mélange d'Access 2000 et 2003, principalement XP SP3 avec quelques anciennes boîtes Win2k. Ils utilisent la réplication de fusion et quelques utilisateurs exécutent des éditions SSEE2005 répliquées et s’abonnent au serveur principal. La plupart des utilisateurs ne sont pas répliqués, se connectant directement au serveur via des connexions client natives ODBC ou SQL. Mais j'ai vérifié que cela arrive à tous les utilisateurs, généralement une ou deux fois par jour, et cela m’est déjà arrivé. Donc, ce n'est pas un problème d'utilisateur.

Le pire dans ce comportement est que cela ne se produit qu’une partie du temps et que je n’ai pas réussi à trouver un scénario qui toujours le faire arriver.

Si quelqu'un a déjà expérimenté quelque chose comme ça, s'il vous plaît, faites-moi savoir comment vous l'avez réglé, ou même des suggestions seraient les bienvenues.

Mettre à jour:  (10/01/09) Problème résolu, grâce à David Fenton. Définir le formulaire en mode de saisie de données (Form.DataEntry = true) avant de l'ouvrir pour ajouter des enregistrements empêche effectivement le saut. Le client ne signale aucun problème depuis que j'ai changé cela il y a une semaine.


12
2017-09-15 05:14


origine


Réponses:


Un client signale des problèmes similaires occasionnels. Il a démarré immédiatement après avoir commencé à utiliser la réplication de fusion.

J'ai informé plusieurs contacts du groupe de produits Microsoft Access, ainsi que mes collègues MVP Access et SQL Server.

S'il vous plaît écrivez-moi votre adresse e-mail afin que je puisse le transmettre à mes contacts chez Microsoft, car je suppose qu'ils voudraient vous contacter directement. tony at granite.ab.ca

BTW excellent dépannage et description détaillée du problème.


8
2017-09-15 05:57



Cela ressemble vraiment à un problème de verrouillage des enregistrements. Utilisez-vous les identifiants comme PK? Avez-vous essayé 2 ordinateurs ajoutant un enregistrement sur le même formulaire en même temps (ce qui signifie que l'un d'entre eux déclenche l'événement d'insertion alors que l'autre a ajouté un nouvel enregistrement sur le formulaire mais l'édite toujours)?

Pourriez-vous vérifier d'une manière ou d'une autre si la PK de l'enregistrement inséré après l'insertion dans la table reste similaire à la PK donnée avant l'insertion (en ajoutant par exemple quelques "debug.print" à votre code)?

Un scénario pourrait être 2 insertions en attente données par la machine sur le même PK, la seconde étant alors automatiquement modifiée au moment de l'insertion, entraînant la perte de l'enregistrement "actif" dans votre formulaire.


4
2017-09-15 14:24



Je m'interroge sur le scénario où vous utilisez un formulaire pour ajouter des enregistrements contenant d'autres enregistrements que l'utilisateur peut sauter.

C'est-à-dire que je ne crois pas en l'utilisation du même formulaire pour éditer les enregistrements que ceux utilisés pour les créer.

Au lieu de cela, j'utiliser une boîte de dialogue non liée pour recueillir tous les champs obligatoires, insérer l'enregistrement dans SQL, puis ouvrez la forme principale d'édition de cet enregistrement unique (pas un formulaire avec toute la table naviguée au dossier qui vient d'être ajouté).

N'oubliez pas que dans un scénario de formulaire / sous-formulaire principal, la création d'un enregistrement dans le sous-formulaire lorsque le formulaire parent n'est pas enregistré entraîne l'enregistrement de l'enregistrement parent. Vous voudrez peut-être vérifier s'il y a du code dans les événements d'insertion et de mise à jour du formulaire principal qui provoquerait une nouvelle requête du formulaire principal sur l'insertion d'un nouvel enregistrement (déclenché par l'édition du sous-formulaire).

Mais je suggérerais quand même que la meilleure architecture consiste à éviter ce genre de scénario possible en ne chargeant que des enregistrements uniques, donc il n’ya pas d’autre enregistrement à sauter. Cela limiterait certainement les possibilités d’accès de l’utilisateur lorsque le problème survient.


3
2017-09-16 01:01



J'ai vu des comportements «similaires» quand il y a plusieurs façons de faire la même chose. (c.-à-d. la tabulation hors de la zone de texte déclenchant le focus perdu ou en cliquant sur un bouton) Assurez-vous que ce n'est pas le cas, si vous ne l'avez pas déjà fait.


1
2017-09-15 14:39



Ce problème est dû au déclencheur de réplication de fusion. Dans ce déclencheur (ce problème a son origine depuis le serveur SQL 2005, dans SQL 2000 Server ce ne sont pas des problèmes), la réplication insère des données dans les tables de réplication avec identités et accède à ce numéro d'identité. J'ai lu que l'accès utilise @@ IDENTITY insetad de SCOPE_IDENTITY et c'est un problème. Pour éviter cela, vous devez modifier le déclencheur de fusion de manière à ce que le déclencheur inséré au début sauvegarde la valeur actuelle de @@ identity in variable et à la fin de la valeur d'insertion dans temp table comme identité avec la valeur de début de la variable. cela corrigera @@ iddentity et les accès obtiendront la juste valeur.

au début de la gâchette  DECLARE @identity int  DECLARE @strsql varchar (128)  set @identity = @@ IDENTITY ar fin quelque chose comme  set @ strsql = 'select identity (int,' + CAST (@identity en varchar (15)) + ', 1) en id dans #temp'  exec (@strsql) et le et il devrait être placé entre     if @@ error <> 0         goto échec
et     revenir

Le problème d'accès ne disparaîtra pas seulement sur la forme mais directement dans la table de liens ODBC.

Je cherche comment ajouter ceci automatiquement pour fusionner le déclencheur de réplication (insert principalement).


1
2017-10-25 16:30



C'est un bogue dans la communication Access et SQL. Accédez à prendre l'identité du nouvel enregistrement à partir de @@ IDENTITY et lorsque vous avez fini de saisir l'enregistrement, rechargez les données en fonction de la valeur de @@ IDENTITY valeur de SQL. Dans SQL 200 inséré, le déclencheur de fusion et l'accès fonctionnent normalement. A partir de SQL 2005, le déclencheur de fusion contient une partie dans laquelle des données sont entrées dans une table de réplication de fusion qui ont une identité avec et modifient la valeur de @IDDENTITY sous la forme d'un enregistrement récemment entré depuis Access.

Une solution consiste à forcer tous les déclencheurs d'insertion de msgege à enregistrer @IDDENTITY en début de variable et à la fin de l'insertion de déclencheur dans la table #temp comme colonne d'identité avec la valeur de départ de la variable préalablement enregistrée.

Cette solution que j'ai trouvée quelque part sur le net quand avant la semaine j'étais aussi touchée par ce problème. Je déplaçais la base de données de SQL 200 vers SQL 2008, puis j'ai trouvé ce problème avec l'identité dans Access. Je soupçonne la réplication car lorsque je supprimais un abonnement, tout commençait à bien fonctionner, mais après l'avoir recréé, il était à nouveau effacé.

Je l'utilise pour résoudre un problème (takem de quelque part sur le net).

au début de la fusion insert trigger

DECLARE @identity int

DECLARE @strsql varchar (128)

set @identity = @@ IDENTITY

et à la fin de la fusion insert trigger

set @ strsql = 'select identity (int,' + CAST (@identity en varchar (15)) + ', 1) en id dans #temp'

exec (@strsql)

le dernier code doit être placé à la place de / * insert end sur cet endroit * / dans le code de réplication de fusion

if @@ error <> 0

goto échec

/ * insérer fin à cet endroit * /

revenir

Mais je cherche un moyen de le faire automatiquement pour tous les déclencheurs de fusion existants lors de la publication et sur tous les déclencheurs de fusion existants sur les abonnements existants et futurs.


1
2017-10-26 14:31



0J'ai trouvé ça

http://jagbarcelo.blogspot.com/search/label/identity

mais je ne sais pas je peux l'utiliser sur SQL 2008.


0
2017-10-26 14:58