VB.NET Problema al actualizar tablas con DATAGRIDVIEW

Tengo dos tablas, ACCESS 2007, relacionadas: ZONAS y PAÍSES. Un país pertenece a una zona y una zona puede tener muchos países.
Atributos de la tabla ZONAS: código-zona, nombre-zona, etc.
Atributos de la tabla PAÍSES: código-país, nombre-país, código-zona, etc.
Para realizar el mantenimiento de las tablas utilizo VB.NET 2012. Tengo un formulario distinto para cada una de ellas, que contiene un DATAGRIDVIEW y un dataset con la tabla correspondiente.
Todo funciona bien (puedo crear datos en cada una de las tablas, guardarlos, visualizarlos, etc) excepto cuando intento modificar un atributo de la tabla ZONAS, p.e. El nombre-zona. El sistema responde con un aviso diciendo que la tabla PAÍSES tiene registros relacionados y que no se puede modificar dicho registro en la tabla ZONAS.
Supongo que la integridad relacional se realiza con el campo código-zona, que no modifico, y por lo tanto no entiendo por qué no puedo modificar el nombre-zona.

He probado también con un solo dataset que contiene las dos tablas pero el sistema da el mismo aviso.

1 respuesta

Respuesta
1

El problema no tiene que ver con VB.NET si no con ACCESS 2007. Cuando creas una relación entre tablas (llave foránea) tienes dos opciones, una es evitar la actualización de los registros que tengan registros relacionados en otras tablas(como es en tu caso), y la otra es permitir la actualización pero también actualizarar los registros que están relacionados. En ACCESS 2007 cuando creas la Relación tienes tres opciones "Exigir Integridad Referencial", "Actualizar en cascada los campos relacionados" y "Eliminar en cascada los campos relacionados". La primera opción es para que las zonas que pongas en cada uno de los registros de tu tabla PAÍSES necesariamente deban existir en la tabla zonas. La segunda opción es para que al actualizar un registro de la tabla ZONA automáticamente se actualicen los registros de la tabla PAÍSES que estén relacionados. La tercera opción es para que al eliminar un registro de la tabla ZONA automáticamente se eliminen los registros de la tabla PAÍSES que estén relacionados. Para tu caso debes activar la primera y segunda opción.

Muchas gracias por tu rápida respuesta.

He realizado lo que me indicas y funciona, pero observo que cuando modifico el nombre de una zona el sistema no responde enseguida sino que tarda unos segundos, parece que está rastreando todas las tablas relacionadas con la tabla zonas (países y otras tablas, algunas con decenas de miles de registros) para transmitir los posibles cambios, cosa que no sería necesaria porque las tablas están normalizadas y sólo comparten las claves (que no cambio).

Antes esta aplicación la tenía en VB6 y la respuesta era inmediata. Las tablas de datos fijos (zonas, países,etc) las actualizaba mediante DATAGRID, uno para cada tabla. He revisado la definición de datos que tenía en ACCESS y he visto que sólo tenía activa la integridad referencial (primera opción).

De nuevo, muchas gracias por tu ayuda y recibe un cordial saludo.

Revisa las relaciones que tengas entre la tabla zonas y la tabla países, probablemente tengas una relación con mas campos y no solo con las claves de las zonas.

Tal como me indicas he revisado las relaciones y sólo están relacionadas las claves.

Por si te da alguna pista, la actualización real de la tabla la realizo en el formclosing mediante la sentencia siguiente:

Me.zonasTableAdapter.Update(Me.Dataset_zonas.zonas)

Parece como que al modificar el nombre de una zona, a ACCESS le llega que se ha modificado el registro, sin distinguir el campo modificado, e interpreta que el código de la zona también se ha modificado/se ha podido modificar.

Muchas gracias por tu atención.

Debes modificar la consulta Update de tu zonasTableAdapter, para esto debes debes hacer clic derecho en el archivo de tu DataSet en el Explorador de Soluciones que se llama Dataset_zonas.xsd, y selecciona Ver Diseñador, en el Diseñador busca la tabla zonas y haz clic en su TableAdapter que seria zonasTableAdapter, en el área de propiedades
hay una propiedad que se llama UpdateCommand, despliega sus atributos y busca el atributo que dice CommandText, ese atributo tiene la consulta update que debes modificar, solo debes quitar la columna de las claves que según tu tabla seria algo como [código-zona] = ? lo que tendrías que quitar, para que no las actualize y así evitar la actualización en cascada innecesaria, también deberías bloquear la posibilidad de editar la clave de la zona, porque aunque se modifique ya no se guardaran los cambios de la clave en la base de datos.

Muchas gracias otra vez.

El código generado por el sistema que figura es el siguiente:

UPDATE zonas_economicas
SET código = ?, nombre = ?, riesgo = ?
WHERE (código = ?) AND (? = 1) AND (nombre IS NULL) AND (? = 1) AND (riesgo IS NULL) OR

(código = ?) AND (? = 1) AND (nombre = ?) AND (riesgo IS NULL) OR
(código = ?) AND (? = 1) AND (nombre IS NULL) AND (riesgo = ?) OR
(código = ?) AND (nombre = ?) AND (riesgo = ?)

He probado a quitar lo que he puesto en negrita (código=?,) pero me da un error cuando ejecuto el programa. No sé si debería quitar más cosas. Si es así, por favor, ¿me lo puedes marcar directamente en la sentencia?

Agradezco de nuevo tu atención.

El código resultante debe ser

UPDATE zonas_economicas
SET nombre = ?, riesgo = ?
WHERE (nombre IS NULL) AND (? = 1) AND (riesgo IS NULL) OR
(nombre = ?) AND (riesgo IS NULL) OR
(nombre IS NULL) AND (riesgo = ?) OR
(nombre = ?) AND (riesgo = ?)

¿Utilizas un Id ademas de código o código es el Id?

código es el Id

He realizado los cambios que me indicas pero cuando actualizo el nombre de una zona se produce el siguiente error:

Excepción no controlada del tipo 'System.Data.OleDb.OleDbException' en System.Data.dll
Información adicional: No coinciden los tipos de datos en la expresión de criterios.

Gracias otra vez.

Ok, es que para hacer el Update se necesita el Id, prueba con este

UPDATE zonas_economicas
SET nombre = ?, riesgo = ?
WHERE (código = ?) AND (? = 1) AND (nombre IS NULL) AND (? = 1) AND (riesgo IS NULL) OR
(código = ?) AND (? = 1) AND (nombre = ?) AND (riesgo IS NULL) OR
(código = ?) AND (? = 1) AND (nombre IS NULL) AND (riesgo = ?) OR
(código = ?) AND (nombre = ?) AND (riesgo = ?)

Sucede lo mismo.

Muchas gracias por tu interés en solucionar mi problema.

En la misma ventana donde encontraste el código de la consulta update se muestra una subventana en la parte de arriba la cual muestra las columnas de la tabla, algunas tienen un lápiz a su lado izquierdo lo que significa que se va a actualizar dicha columna(es decir se incluye en la consulta update), verifica que tu columna código no tenga el lápiz, si tiene el lápiz haz clic en el lápiz para quitarlo, después haces clic en aceptar para guardar los cambios

Ya lo había probado y tampoco funciona.

Intenta volver a generar las consultas(Clic derecho a zonasTableAdapter y seleccionar configurar), después vuelve a revisar la consulta Update para ver si la columna código tiene el lápiz a su izquierda, si lo tiene es porque no tienes definido la columna código como primary key en Access.

He realizado lo que me indicas pero el problema se repite. He revisado las claves y, en la tabla zonas, código es la única clave y está declarada como clave principal. No obstante, en el zonasTableAdapter la columna código tiene el lápiz a la izquierda.

Para facilitar las modificaciones, he creado desde cero una mini-aplicación sólo con las dos tablas ACCESS, sus correspondientes dataset, y dos formularios con sus correspondientes datagridview, pero se repite el mismo problema. También en zonasTableAdapter la columna código sigue con el lápiz a la izquierda.

Al crear las tablas ACCESS el sistema propone la columna Id como primary key, pero he eliminado esa columna y he marcado código como clave principal.

Muchas gracias y ruego me disculpes por tantas molestias.

Ok, estuve reproduciendo el error y ya logre evitarlo haciendo lo mas simple posible la consulta update y quedo así

UPDATE zonas_economicas
SET nombre = ?, riesgo = ?
WHERE (código = ?)

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas