Foros del Web » Programación para mayores de 30 ;) » .NET »

Actualizar una tabla en base a otra

Estas en el tema de Actualizar una tabla en base a otra en el foro de .NET en Foros del Web. Hola, Intento hacer una actualizacion sobre una bd en base a otra y buscando encontre muchos posts y ejemplos aunque no pude hacer funcionar ninguno. ...
  #1 (permalink)  
Antiguo 02/12/2008, 11:57
 
Fecha de Ingreso: agosto-2002
Mensajes: 202
Antigüedad: 21 años, 8 meses
Puntos: 1
Actualizar una tabla en base a otra

Hola,

Intento hacer una actualizacion sobre una bd en base a otra y buscando encontre muchos posts y ejemplos aunque no pude hacer funcionar ninguno.

Tengo dos tablas en bases de datos distintas, pero que en principio serian del mismo tipo (access) y con la misma estructura.

Mi intencion es actualizar una tabla en base a la otra. Cuando un registro tenga un valor distinto al de la otra tabla en un determinado campo (que desde ya no seria la clave) deberia actualizar ese campo. En el caso de que un registro no exista agregarlo y en el caso de que haya sido borrado de la tabla principal, borrarlo en la secundaria. Todo esto no seria de forma sincrnoizada sino en determinado momento, por ejemplo al clickear en un boton.

Para intentar resolverlo lo que hice fue armar dos datasets, uno sobre cada tabla y luego utilizar el metodo merge, pero no funciona y seguramente hay mas de un error en el codigo. Aunque no se genera ninguna excepcion, las actualizaciones no se realizan.



Código:
Dim sqlstr As String = "select * from personas"

conexion.Open()
Dim ds As New DataSet
Dim da As New OleDb.OleDbDataAdapter(sqlstr, conexion)

da.Fill(ds)

conexion2.Open()
Dim ds2 As New DataSet
Dim da2 As New OleDb.OleDbDataAdapter(sqlstr, conexion2)
da2.Fill(ds2)

ds.AcceptChanges()
ds2.Merge(ds)

da.Update(ds)

conexion.Close()
conexion2.Close()
Una segunda opcion que se me ocurrio seria utilizar un tercer dataset y a traves tambien del metodo merge incluir en el solo las filas distintas. Luego habria que ir recorriendolo y hacer las actualizaciones una por una, pero creo que tendria un rendimiento malo y no estoy seguro si es la forma correcta.

Desde ya agradezco por cualquier ayuda o sugerencia,

Leo
__________________
Principio Legal Legalidad en la web y Directorio de Software Open Source
Pais Once El lugar donde descubrir una ciudad
  #2 (permalink)  
Antiguo 03/12/2008, 09:20
 
Fecha de Ingreso: noviembre-2008
Ubicación: Madrid, España
Mensajes: 149
Antigüedad: 15 años, 5 meses
Puntos: 5
Respuesta: Actualizar una tabla en base a otra

Hola,

Desde aquí veo un par de errores en el código que presentas. Quizá esto te pueda ayudar.

El primer error consiste en llamar a "AcceptChanges" en ds antes de haber hecho ninguna operación sobre el dataset. Tal y como está ubicado en ese código, esta línea no hace nada. La idea es llamar a AcceptChanges justo antes de llamar a Update, y lo debes hacer sobre el dataset que vayas a actualizar, no sobre el origen.

El segundo es que la llamada a Merge la haces desde ds2. Es decir, el dataset que se actualiza es ds2 y no ds. A continuación, estás llamando a update sobre ds, que sólo se ha utilizado como parámetro en la operacion merge y, por tanto, no ha cambiado.

Espero que con esta información logres hacer funcionar la historia. No creo que el tercer dataset sea necesario, creo que tus problemas provienen por la utilización incorrecta de los métodos de la clase DataSet.

Un saludo
  #3 (permalink)  
Antiguo 03/12/2008, 13:14
 
Fecha de Ingreso: agosto-2002
Mensajes: 202
Antigüedad: 21 años, 8 meses
Puntos: 1
Respuesta: Actualizar una tabla en base a otra

Hola nephilim,

Antes que nada muchas gracias por tu respuesta en el post.

La llamada a acceptchanges la he movido justo antes del update. Con respecto a lo demas, en realidad ds2 era el origen ya que solo se abria ocasionalmente para actualizar a ds que es el nombre que utilizo como dataset en todo el programa. De todas formas cambie los nombres para que no quede tan confuso.

Código:
Dim ds_origen As New DataSet
Dim da_origen As New OleDb.OleDbDataAdapter(sqlstr, conexion_origen)
da_origen.Fill(ds_origen)

Dim ds_destino As New DataSet
Dim da_destino As New OleDb.OleDbDataAdapter(sqlstr, conexion_destino)
da_destino.Fill(ds_destino)


ds_destino.Merge(ds_origen)

ds_destino.AcceptChanges()
da_destino.Update(ds_destino)

conexion_destino.Close()
conexion_origen.Close()
Aun no funciona, aunque no genera ninguna excepcion ni nada por el estilo.

De todas formas hay algo que no entiendo. Yo en ningun momento le estoy indicando al dataset que campo es que campo, ni los tipos de datos, ni nada de eso. Las bases de datos son exactamente iguales debido a que hice la copia una de la otra y solo modifique el valor un campo para ver la actualizacion.

Pero en la aplicacion real no deberia indicar nada sobre la estructura de las tablas? De todas formas me gustaria poder hacerlo funcionar al menos en este caso, es decir donde no hay ninguna diferencia entre las bases de datos, mas que los valores de las filas a actualizar.
__________________
Principio Legal Legalidad en la web y Directorio de Software Open Source
Pais Once El lugar donde descubrir una ciudad
  #4 (permalink)  
Antiguo 04/12/2008, 03:39
 
Fecha de Ingreso: noviembre-2008
Ubicación: Madrid, España
Mensajes: 149
Antigüedad: 15 años, 5 meses
Puntos: 5
Respuesta: Actualizar una tabla en base a otra

En un principio, y hasta donde yo sé, las librerías de ADO.Net no necesitan que les facilites esa información, ya que la obtienen directamente de la base de datos al recuperar la información. Si pones un punto de interrupción en ese código y analizas el contenido de los dataset, verás que tienen sus objetos Datatable, que a su vez tienen una colección de DataColumn, que definen la estructura de las columnas de una Datatable, y en los que tienes información como el nombre de la columna o el tipo de datos.

El Merge comprobará si la estructura del dataset a "mergear" es compatible con la del dataset "mergeado" y, si es así, comparará fila a fila las tablas de los dataset para determinar como realizar la combinación. Una propiedad interesante de la clase DataRow es RowState que te indica, desde que se cargó, si el contenido o el estado de la fila ha cambiado (incluido si la fila ha sido eliminada).

Tal como está el código y, si no te genera ningún error, se me ocurre que quizá el problema pudiera venir de que tengas alguno de los archivos Access abierto. En otro caso, debería funcionar. Yo consultaría el contenido del dataset que vas a guardar una vez realizado el merge para ver si, efectivamente, contiene la información que debería contener (es decir, el resultado de combinar los dos datasets. Ten en cuenta que si ambos datasets tienen las mismas filas con los mismos ids, el resultado del merge sería no hacer nada, puesto que la comparación devolverá que ambos datasets son idénticos.

P.D: Una vez cerrada una conexión, estaría bien que hicieses una llamada a los métodos dispose, primero en los OleDbDataAdapter y después en los Connection. Así garantizas que no queda "basura" suelta por ahí ;)
  #5 (permalink)  
Antiguo 04/12/2008, 23:25
 
Fecha de Ingreso: agosto-2002
Mensajes: 202
Antigüedad: 21 años, 8 meses
Puntos: 1
Respuesta: Actualizar una tabla en base a otra

Hola,

Aun no he conseguido hacerlo funcionar, pero encontre varias cosas.

En primer lugar hice las pruebas que me sugeriste y encontre algo que no esperaba. El dataset luego del merge deberia tener los datos actualizados o bien en el peor de los casos los datos originales sin actualizarse.

En realidad no se da ninguna de las dos opciones. El dataset tiene los datos de las dos tablas, es decir en el caso de las filas con algun cambio aparecen la original y la modificada y en el caso de las filas completamente iguales aparece la misma dos veces.

Esto me parecio raro debido a que en el dataset aparece dos veces cada clave. Lo primero que hice es verificar que en la bd que esten definidas como clave esas columnas y comprobe que estan correctamente definidas.

Luego lei un articulo que explica el mismo problema e indica que si el dataset no devuelve true al ejecutar el metodo haschanges() la base de datos no se actualiza. Hice la comprobacion y devolvia false, por lo tanto segun este articulo debo agregar antes de llenar el dataset la siguiente linea:

Código:
da_destino.AcceptChangesDuringFill = False

probe hacerlo para cada uno de los datasets y para ambos y logre que el dataset devuelva true para haschanges, pero la base de datos sigue sin actualizarse y dificlmente lo haga debido a lo de las filas duplicadas en el dataset. Actualmente el codigo quedo asi:


Código:
Dim sqlstr As String = "select * from personas"

conexion_origen.Open()
conexion_destino.Open()

Dim ds_origen As New DataSet
Dim da_origen As New OleDb.OleDbDataAdapter(sqlstr, conexion_origen)
da_origen.Fill(ds_origen)

Dim ds_destino As New DataSet
Dim da_destino As New OleDb.OleDbDataAdapter(sqlstr, conexion_destino)
da_destino.AcceptChangesDuringFill = False
da_destino.Fill(ds_destino)
Dim resultado As Boolean = ds_destino.HasChanges

ds_destino.Merge(ds_origen)
ds_destino.AcceptChanges()
da_destino.Update(ds_destino)

datagridview1.DataSource = ds_destino.Tables(0)

conexion_destino.Close()
conexion_origen.Close()
da_origen.Dispose()
da_destino.Dispose()
conexion_origen.Dispose()
conexion_destino.Dispose()

Ya no se que mas probar. Como comentaba antes hay muchos posts sobre como realizar esto que parece bastante simple, pero no funciona.

Saludos,
Leo
__________________
Principio Legal Legalidad en la web y Directorio de Software Open Source
Pais Once El lugar donde descubrir una ciudad
  #6 (permalink)  
Antiguo 05/12/2008, 01:37
 
Fecha de Ingreso: noviembre-2008
Ubicación: Madrid, España
Mensajes: 149
Antigüedad: 15 años, 5 meses
Puntos: 5
Respuesta: Actualizar una tabla en base a otra

Lo cierto es que es raro. Yo creo que durante mi vida laboral habré utilizado una vez el merge y no me dio problemas. ¿Has comprobado si los campos que son clave primaria vienen definidos en el dataset como tales? Otra cosa que te puede ocurrir (aunque, según mi experiencia, debería levantarte una excepción) es que la query que hayas utilizado para cargar los datasets combine datos de tablas distintas o utilice funciones de agregado.

Me explico: el dataadapter genera las consultas de actualización automáticamente a partir de la consulta de recuperación a través de la cual han sido creada; y parece que las reglas para posibilitar esta generación son bastante estrictas, con lo cual la presencia de alguno de los elementos que te comento provoca que la consulta de actualización no se genere correctamente. Para estos casos, la solución es sencilla, ya que el dataadapter de permite especificar un updatecommand, un insertcommand y un deletecommand. Quizá con esto se pueda resolver tu problema de modificación de datos en BDD. Otra cosa es el tema del merge. Intentaré echar un ojo a trabajo que tengo hecho con Access para ver si puedo encontrar alguna pista que te ayude a solucionar el tema :)

Un saludete
  #7 (permalink)  
Antiguo 18/04/2009, 21:11
 
Fecha de Ingreso: marzo-2008
Mensajes: 2
Antigüedad: 16 años, 1 mes
Puntos: 0
Respuesta: Actualizar una tabla en base a otra

Buenas,

Si aun estoy a tiempo quisiera darte mi opinión en base a mi experiencia.
El problema de tu código reside en llamar a AcceptChanges() antes de realizar el update, porque esto lo que hace es marcar todos los registros modificados como no modificados (Acepta todos los cambios) por lo cual el metodo Update() no encuentra registros a actualizar.

Esa linea de codigo deberías de ponerla luego del Update().

Espero haber sido de ayuda.

Saludos
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 06:51.