2009-09-15 19 views
12

Realmente estoy publicando esto por desesperación después de buscar mucho por una respuesta y probar algunas cosas diferentes sin éxito.El acceso a veces salta al registro existente en Guardar nuevo registro - Access2k FE/SQL2005 BE

Tengo una base de datos de Access donde recientemente migré las tablas a SQL 2005, Access continúa funcionando para los usuarios como un front-end que proporciona formularios, informes y consultas.

Sin embargo, desde su traslado a la FE Acceso/SQL SER configuración, los usuarios han estado informando que veces, cuando están entrando en un nuevo disco, que encajen en un subformulario (guardar el registro) o haga clic en Guardar en el menú, salta a un registro existente. El nuevo registro se ha guardado, pero por algún motivo el acceso cambia a un registro diferente a medida que se actualiza. El usuario debe cerrar, buscar el registro guardado y continuar editándolo.

Escenario: un usuario entra en una cita y llena todos los detalles de cotización, cliente, fecha, etc, a continuación, hace clic en el line-artículos SUBFORM para añadir un producto (o hace clic en Guardar en el menú), y de repente el formulario de cotización (y el subformulario de línea de pedido) muestra los detalles de alguna cotización aleatoria. La cita aleatoria podría ser reciente, o de hace años, y no tiene nada en común con la cita que estaban ingresando.

Este comportamiento extraño solo ocurre al insertar un nuevo registro, nunca al editar un registro existente. Los usuarios me dicen que sucede 'con más frecuencia' cuando van a agregar una nueva (cita, cliente, lo que sea) después de abrir la base de datos.

He notado que solo está sucediendo en formularios que tienen subformularios, así que mi primer pensamiento es que tiene que ver con el envío de Access a través de los datos del subformulario antes de que se guarden los datos del formulario, causando una violación de PK. Pero esto no parece estar sucediendo: no hay errores en el servidor SQL, y el registro se guarda con éxito. Obligar a los usuarios a guardar el registro de formulario principal antes de agregar registros de subformulario (es decir, en una cotización, obligándoles a guardar la cotización antes de que puedan agregar líneas de pedido) no funcionó, solo causa el salto (a veces) en la operación de guardar.

No estoy ejecutando vba en el guardado o en el actual, he establecido puntos de interrupción en todos los controladores de eventos a medida que salta y no se está ejecutando vba. Algunas de las formas 'saltar' no tienen vba en la forma. Pero todos tienen subformularios. Sospecho que tiene que ver con el bloqueo de registros.

El servidor que ejecuta las tablas es SQL Server 2005, los usuarios utilizan una combinación de Access 2000 y 2003, principalmente XP SP3 con un par de cajas viejas de Win2k. Están utilizando la duplicación de Merge y un par de usuarios están ejecutando ediciones de SSEE2005 replicadas y suscribiéndose al servidor principal. La mayoría de los usuarios no se replican, simplemente se conectan directamente al servidor a través de conexiones de cliente nativas ODBC o SQL. Pero he verificado que esto le está sucediendo a todos los usuarios, generalmente una o dos veces al día, y me ha sucedido antes. Por lo tanto, no es un problema del usuario.

La peor parte de este comportamiento es que solo ocurre algunas veces y no he podido encontrar un escenario que siempre haga que ocurra.

Si alguien ha experimentado algo así antes, hágamelo saber cómo lo resuelve, o incluso las sugerencias serían bienvenidas.

Actualización: (1/10/09) Problema resuelto, gracias a David Fenton.Configurar el formulario al modo de Entrada de Datos (Form.DataEntry = true) antes de abrirlo para agregar registros, de hecho previene el salto. El cliente informa que no hubo ningún problema desde que cambié esto hace una semana.

+0

¿Está utilizando claves primarias y una marca de tiempo conocido como rowversion en todas las mesas? Supongo que estás usando teclas principales ya que suenas bastante competente, pero tengo que preguntar. –

+1

Sí, todas las tablas tienen PK e identidad. Traté de agregar TimeStamp en un par de tablas (el Cita y las líneas de pedido) y no hizo ninguna diferencia en este problema. –

+0

(Tony, puede copiar su comentario en el portapapeles, eliminarlo y luego reemplazarlo con un nuevo comentario con sus correcciones) –

Respuesta

8

Un cliente está reportando ocasionalmente problemas similares. Comenzó inmediatamente después de que comenzaron a usar la duplicación de mezcla.

He informado a varios contactos dentro del grupo de productos de Microsoft Access, así como a mis compañeros Access y MVPs de SQL Server.

Por favor envíeme un correo electrónico a su dirección de correo electrónico para que pueda reenviarlo a mis contactos en Microsoft, ya que supongo que querrían contactarlo directamente. tony en granite.ab.ca

BTW excelente solución de problemas y descripción detallada del problema.

+0

Gracias Tony, correo electrónico enviado. –

+1

Pregunta estúpida. ¿Puedes desactivar la replicación de mezcla por un tiempo para ver si eso realmente causa el problema? –

+1

Pregunta para usted: ¿Ha revisado el visor de conflictos para ver si se registraron conflictos? Comentario: Algo similar ocurre en Access cuando tiene uniqueidentifier como clave principal en la tabla del servidor sql, o algún otro tipo de campo con valor autogenerado. ¿Tiene int con identidad como PK? Cualquier desencadenante? –

4

Definitivamente suena como un problema de bloqueo de registros. ¿Estás usando autonumbers como PK? ¿Has probado 2 computadoras agregando un registro en el mismo formulario al mismo tiempo (es decir, uno de ellos activará el evento de inserción mientras que el otro ha agregado un nuevo registro en el formulario uno pero aún lo está editando)?

Podría comprobar de una manera u otra si el PK del registro insertado después de inserción en la tabla se mantiene similar a la PK determinado antes de la inserción (añadiendo, por ejemplo, unos pocos 'Debug.Print de que su código) ?

Un escenario podría ser 2 inserciones pendientes otorgadas por la máquina con la misma PK, la segunda se cambiará automáticamente en el momento de la inserción, lo que hará que su forma pierda el registro 'activo'.

+1

Gracias, es una buena sugerencia Philippe, pero no creo que pueda ser la causa del problema. Sí, PK es autónomo tanto en los objetos en la forma como en el subformulario, pero no creo que sea PK porque también está sucediendo en clientes replicados, no solo no están en la red, sino que tienen segmentos PK particionados. –

+0

Entonces estoy convencido de que tiene algo que ver con este problema de autonumeración. Por cierto, los segmentos PK con autoniveles divididos son realmente una pita. Supongo que los autonumbers se heredaron de una actualización de Access a SQL Server. –

1

He visto el comportamiento "me gusta" cuando hay varias maneras de hacer lo mismo. (es decir, tabular fuera del cuadro de texto activando el punto perdido frente a hacer clic en un botón). Así que asegúrese de que este no sea el caso, si aún no lo ha hecho.

3

Me pregunto acerca de la situación en la que está usando un formulario para agregar registros que tienen otros registros para que el usuario pueda saltar.

Es decir, no creo en usar el mismo formulario para editar registros que se usa para crearlos. En su lugar, utilizo un diálogo independiente para recopilar todos los campos requeridos, inserte el registro en SQL y luego abra el formulario de edición principal a ese único registro (no un formulario con toda la tabla navegada al registro que acaba de agregar)

Tenga en cuenta que en un escenario de formulario principal/subformulario, la creación de un registro en el subformulario cuando el formulario principal no se guarda hace que se guarde el registro padre. Es posible que desee comprobar si hay algún código en los eventos Insertar y Actualizar del formulario principal que provocaría una nueva consulta del formulario principal en la inserción de un nuevo registro (desencadenado por la edición del subformulario).

Pero aún así sugeriría que la mejor arquitectura es evitar este tipo de escenario posible cargando solo registros individuales, por lo que no hay otro registro al que saltar. Eso ciertamente limitaría las posibilidades de dónde el usuario podría terminar cuando ocurra el problema.

+0

"crear un registro en el subformulario cuando el formulario principal no se guarda hace que se guarde el registro principal." Tan pronto como haga clic en cualquier parte del área del subformulario, Access guardará el registro principal. Sin embargo, generalmente estoy en desacuerdo con el enfoque de un diálogo separado. O mejor dicho, no veo ninguna razón para ello. Un formulario para inserciones y actualizaciones debería funcionar y funcionar bien. Y si Access tiene un error en estas circunstancias, debe ser arreglado por MS –

+0

Desafortunadamente no diseñé estos formularios, y los usuarios (vendedores, administradores, administradores, ingenieros) están todos acostumbrados a la creación y edición en la misma forma. Utilizo una forma independiente y sin delimitar que inserta el registro en SQL como usted me sugirió (de hecho, esto ya lo hago en una serie de otros diálogos de solo creación), solo que no sé cómo me las arreglaré para completar los elementos del subformulario, y Me gustaría evitar tener que volver a escribir todos estos formularios si no es necesario. Comprobaré esos eventos, pero sé que hay algunos formularios que muestran este comportamiento que no tienen vba. Gracias –

+0

"Algunas formas que exhiben este comportamiento no tienen vba" Ok, eso es bueno saberlo. –

1

Este problema está codificado por el desencadenador de duplicación de mezcla. En este desencadenador (este problema desde SQL Server 2005, en el servidor SQL 2000 esto no es un problema) la replicación inserta algunos datos en las tablas de replicación con identidades y accede a obtener este número de identidad en lugar de inserción de identidad real. Leí ese acceso use @@ IDENTIDAD insertada de SCOPE_IDENTITY y este es un problema.Para evitar esto, debe cambiar el desencadenador de fusión de manera que en el desencadenador de inserción al comienzo guarde el valor actual de @@ identidad en la variable y al final del valor de inserción del desencadenante en la tabla temporal como identidad con el valor inicial de lo que está escrito en la variable. esto corregirá @@ iddentity y acceso obtendrá el valor correcto.

a empezar de gatillo DECLARE @identity int DECLARE VARCHAR @strsql (128) conjunto @identity = @@ IDENTITY terminan ar algo así como conjunto @ strsql = 'identidad select (int,' + CAST (@ identidad como varchar (15)) + '1) como ID en #temp' exec (@strsql) et al y se debe colocar entre si @@ error <> 0 FALLO Goto
y retorno

El problema de acceso no solo se reflejará en la forma pero directamente en la tabla de enlace ODBC también.

Estoy buscando la manera de agregar esto automáticamente para fusionar el disparador de replicación (principalmente insertar).

+0

Si bien el punto sobre SCOPE_IDENITY() en un escenario con desencadenadores es bueno, no hay evidencia de que eso tenga algo que ver con esta pregunta hasta donde puedo ver. ¿Puede explicar cómo su respuesta es realmente relevante aquí? ¿O estás haciendo una nueva pregunta por completo? –

1

Este es un error en el acceso y la comunicación SQL. El acceso toma la identidad del nuevo registro desde @@ IDENTIDAD y cuando termina de ingresar el registro, recarga datos basados ​​en el valor del @@ IDENTITY valor de SQL. En SQL 200, el disparador de combinación insertado y el acceso normalmente funcionan bien. Desde el desencadenador de combinación de SQL 2005, tiene una parte en la que los datos se ingresan en alguna tabla de duplicación de fusión que tienen identidad y cambian el valor de @IDDENTITY del que acaba de ingresar el rcord de Access.

Una solución es utilizar todo el disparador de inserción para guardar @IDDENTITY al comienzo de la variable y al final del disparador insertar el registro dumy en la tabla #temp como columna de identidad con el valor de inicio de la variable previamente guardada.

Esta solución la encontré en algún lugar de la red cuando antes de la semana también me afectaba este problema. Estaba moviendo la base de datos de SQL 200 a SQL 2008 y luego encontré este problema con la identidad en Access. Sospecho la replicación porque cuando estaba eliminando una suscripción, todo comenzó a funcionar bien, pero después de volver a crearlo, se borró.

Lo uso para resolver un problema (takem desde algún lugar de la red).

en el comienzo de gatillo de combinación de inserto

DECLARE @identity int

DECLARE @strsql varchar (128)

conjunto @identity = @@ IDENTITY

y al final de merge insert trigger

set @ strsql = 'seleccionar identidad (int,' + CAST (@identidad como varchar (15)) + ', 1) como id en #temp'

exec (@strsql)

último código debe colocarse en el lugar de/* inserte el extremo en este lugar */en el código de replicación de mezcla

si @@ error <> 0

Goto FALLO

/* inserte el extremo en este lugar */

retorno

Pero estoy buscando una manera de hacerlo automáticamente para todos los disparadores de fusiones existentes en la publicación y en todos los desencadenantes de fusiones existentes en suscripciones existentes y futuras.

+0

Nuevamente, ha publicado otra respuesta cuando debería comenzar su propia pregunta. En realidad, no hay evidencia real de que el problema que tuvo el póster original esté relacionado con el problema desencadenante/SCOPE_IDENTITY(). –

Cuestiones relacionadas