Perdida de datos
Hola, una pregunta ... Tengo varios formularios de inserción y modificación donde utilizo transacciones. Y no se si esto tendrá que ver o no con mi problema.
Inserto datos y trabajo con ellos perfectamente, pero en ocasiones (escasas) al cerrar la aplicación y volverla a abrir, resulta que los datos que he insertado o modificado en la sesión (comprendiendo desde que accedí hasta que cerré el programa) han desaparecido (es como si en realidad no hubiera estado haciendo nada).
¿A qué podría deberse?
Gracias.
Inserto datos y trabajo con ellos perfectamente, pero en ocasiones (escasas) al cerrar la aplicación y volverla a abrir, resulta que los datos que he insertado o modificado en la sesión (comprendiendo desde que accedí hasta que cerré el programa) han desaparecido (es como si en realidad no hubiera estado haciendo nada).
¿A qué podría deberse?
Gracias.
3 Respuestas
Respuesta de emperador20
1
1
Tiene mucho que ver, porque hay cuatro formas distintas de abrir los recordset
Solo lectura, escritura-lectura, y otras dos que no me acuerdo.
Si vos abrís un recordset solo lectura o lectura parcial (creo) vas a modificar solo para tus ojos pero no en la base.
Creo que tendrías que declarar un command y usarlo porque el gconexion.execute (sql) es una propiedad fuerte del command y no de la conexión.
Solo lectura, escritura-lectura, y otras dos que no me acuerdo.
Si vos abrís un recordset solo lectura o lectura parcial (creo) vas a modificar solo para tus ojos pero no en la base.
Creo que tendrías que declarar un command y usarlo porque el gconexion.execute (sql) es una propiedad fuerte del command y no de la conexión.
Hola leandro, a ver ...
-Accedo mediante declarando una conexión y un recordset ODBC
-No, no uso dataenvironment
-Pues, es esporádico. A veces no pasa nada, pero ya me ha pasado un par de veces que tras introducir varios datos y utilizarlos (por ejemplo, crear una obra e imprimir los datos de esta, y crearte partes de trabajo asociados), al cerrar la aplicación, dichos datos no están.
-Ah! La base de datos es Access
Muchas gracias por tu tiempo.
-Accedo mediante declarando una conexión y un recordset ODBC
-No, no uso dataenvironment
-Pues, es esporádico. A veces no pasa nada, pero ya me ha pasado un par de veces que tras introducir varios datos y utilizarlos (por ejemplo, crear una obra e imprimir los datos de esta, y crearte partes de trabajo asociados), al cerrar la aplicación, dichos datos no están.
-Ah! La base de datos es Access
Muchas gracias por tu tiempo.
Ok, te he agregado. A ver si me echas una manilla cuando coincidamos, porque no me ha quedado muy claro eso del execute.
Y ... gracias por tu interés.
Y ... gracias por tu interés.
Pero ... yo no actualizo sobre el recordset abierto, sino directamente sobre una instrucción INSERT o UPDATE utilizando directamente la clave de la tabla. NO se si me he explicado bien :s
Pero ... si el fallo está al actualizar o insertar los datos, ¿qué tiene que ver la forma de abrirlo? Ya que lo que me muestra el recordset es lo que realmente esta en la bd
Conexión
Public gConexion As ADODB.Connection
Set gConexion = New ADODB.Connection
gConexion.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source = " & BDstr & "BaseDatosTienda.mdb;Persist Security Info=False"
gConexion.Open
------------
Recordset
Set oRS = gConexion.Execute(sQS) -> sQS ES LA CADENA CON EL SELECT
------------
Actualizaciones o inserciones
Construyo un sql con el INSERT o el UPDATE y luego lo ejecuto de la siguiente forma: gConexion.Execute(sQS)
Public gConexion As ADODB.Connection
Set gConexion = New ADODB.Connection
gConexion.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source = " & BDstr & "BaseDatosTienda.mdb;Persist Security Info=False"
gConexion.Open
------------
Recordset
Set oRS = gConexion.Execute(sQS) -> sQS ES LA CADENA CON EL SELECT
------------
Actualizaciones o inserciones
Construyo un sql con el INSERT o el UPDATE y luego lo ejecuto de la siguiente forma: gConexion.Execute(sQS)
Es la forma que usas los recordset
lo usas como si usarias un command.
tendrias que trabajarlo asi
dim rs as adodb.recordset
set rs = new recordset
rs.open consulta,gconexion,lockeo, cursor
o declarar algo como command
lo usas como si usarias un command.
tendrias que trabajarlo asi
dim rs as adodb.recordset
set rs = new recordset
rs.open consulta,gconexion,lockeo, cursor
o declarar algo como command
Este es mi msn
[email protected]
Si tienes msn así hablamos mejor.
Olvidate de los recordset el problema es como utilizas el execute.
[email protected]
Si tienes msn así hablamos mejor.
Olvidate de los recordset el problema es como utilizas el execute.
- Compartir respuesta
- Anónimo
ahora mismo
Respuesta de jusbet
1
1
jusbet, Hola a todos! En este momento estoy sumamente ocupada en un nuevo...
ok... ¿tienes una tabla de usuarios o los inicio de sesión los hace mediante windows? Es muy importante que veas esto, porque si estas trabajando dentro de una red (el programa), quizá estés utilizando la base de datos equivocada... la pregunta seria: ¿Cómo controlas el trafico de solicitudes? Puede ser que cuando un usuario haga modificación u otra, otro este solicitando una consulta, y todavía access no sabe como solucionar la situación. Si es esto lo que te sucede, lo mejor seria que hicieras el esfuerzo de cambiar access por SQL, ya que el segundo controla este trafico de manera automática y permite lo necesario para la integridad de datos, que es lo que te esta sucediendo.
En segundo lugar, puedes que estés usando mal los punteros de ado o los bloqueos (adlockreadonly, adlockoptimistic)...
Es necesario que me respondas lo siguiente:
1) Tu aplicación trabaja dentro de una red)
2) ¿Usas conexiones DAO o ADO?
3) ¿Qué clase de bloqueo usas?
Recuerda que para hacer cualquier operación con recordset, primero tienes que establecer la forma de bloqueo, acuérdate que access no hace esto por si mismo.
También una pregunta interesante seria como estas haciendo las operaciones de insercion/modificacion/eliminacion/consulta. Escríbeme el código para ver que estas haciendo mal...
Escríbeme pronto, deseo en realidad ayudarte.
Bye!
En segundo lugar, puedes que estés usando mal los punteros de ado o los bloqueos (adlockreadonly, adlockoptimistic)...
Es necesario que me respondas lo siguiente:
1) Tu aplicación trabaja dentro de una red)
2) ¿Usas conexiones DAO o ADO?
3) ¿Qué clase de bloqueo usas?
Recuerda que para hacer cualquier operación con recordset, primero tienes que establecer la forma de bloqueo, acuérdate que access no hace esto por si mismo.
También una pregunta interesante seria como estas haciendo las operaciones de insercion/modificacion/eliminacion/consulta. Escríbeme el código para ver que estas haciendo mal...
Escríbeme pronto, deseo en realidad ayudarte.
Bye!
Lo que t esta pasando es que no bloqueas las operaciones...
Prueba con esto a ver como te va:
conx= variable de conexion
rs= recordset
******INSERTAR*************
sql= "Select * From Tabla"
set rs= new adodb.recordset
Rs. Open sql, conx, adopenkeyset, adlockoptimistic
rs.addnew
rs.fields("Campo").value= text1.text
---------
---------
rs.update
rs.close
*****************************
bloqueos:
1) AdLockReadOnly: predeterminado. De solo lectura; no puede modificar datos. Produce los conjunto de resultados con menor impacto y es el más fácil de escalar. Usalo solo para consultas... Ejemplo:
sql="select * from tabla"
set rs= new adodb.recordset
rs.open sql, conx, adopenkeyset, adlockreadonly
if not rs.eof then
Xxxxxxx
Xxxxxxx
Endif
Rs. Close
2)AdlockPessimistic: Bloqueo pesimista, registro a registro. Es el más difícil de escalar porque bloquea filas o páginas nada más producirse la apertura, y esos bloqueos se mantienen mientras el cursor se mantiene abierto. Solo esta disponible del lado del servidor (NO TE LO RECOMIENDO)
3) AdLockOptimistic: Bloqueo optimista, de registro a registro; el proveedor solo bloquea registros cuando llama al método update. Es de menor impacto. (Usalo para actualizar, insertar)
4) AdLockBatchOptimistic: actualizaciones optimistas por lotes; es necesario para actualizar por lotes, en lugar del modo de actualización automático. Solo puede emplearse con cursores estáticos construidos con las bibliotecas del lado del cliente.
Para poder trabajar con ellos, necesitas de los cursores:
1) AdOpenForwardOnly: De solo avance. Disponible del lado del servidor. Usalo solamente para operaciones de solo lectura.
2)AdOpenStatic: Del lado del cliente. Es difícil explicar como funciona, solo te diré que no te lo recomiendo porque es como tomar una copia estática de resultados.
3) AdOpenKeyset: (MI FAVORITO). Disponible del lado del servidor. Cursor de conjunto de claves igual que un cursor dinámico, excepto porque no es posible ver los registros que añadan otros usuarios. Este de lectura/escritura, totalmente desplazable. Es mucho más económico que el dynamic.
4) AdOpenDynamyc: (TAMBIÉN ES MI FAVORITO, USALO PARA INSERTAR, MODIFICAR, ELIMINAR). Todos los cambios realizados por otro usuarios serán visibles, y están permitidos para todos los desplazamiento de recordset. Es el más costoso, un poco más lento.
Si puedes usar todo el tiempo el keyset, es el mejor...
De todas maneras prueba esto, espero te funcione... si necesitas más información, escríbeme de nuevo. Hasta pronto!
Prueba con esto a ver como te va:
conx= variable de conexion
rs= recordset
******INSERTAR*************
sql= "Select * From Tabla"
set rs= new adodb.recordset
Rs. Open sql, conx, adopenkeyset, adlockoptimistic
rs.addnew
rs.fields("Campo").value= text1.text
---------
---------
rs.update
rs.close
*****************************
bloqueos:
1) AdLockReadOnly: predeterminado. De solo lectura; no puede modificar datos. Produce los conjunto de resultados con menor impacto y es el más fácil de escalar. Usalo solo para consultas... Ejemplo:
sql="select * from tabla"
set rs= new adodb.recordset
rs.open sql, conx, adopenkeyset, adlockreadonly
if not rs.eof then
Xxxxxxx
Xxxxxxx
Endif
Rs. Close
2)AdlockPessimistic: Bloqueo pesimista, registro a registro. Es el más difícil de escalar porque bloquea filas o páginas nada más producirse la apertura, y esos bloqueos se mantienen mientras el cursor se mantiene abierto. Solo esta disponible del lado del servidor (NO TE LO RECOMIENDO)
3) AdLockOptimistic: Bloqueo optimista, de registro a registro; el proveedor solo bloquea registros cuando llama al método update. Es de menor impacto. (Usalo para actualizar, insertar)
4) AdLockBatchOptimistic: actualizaciones optimistas por lotes; es necesario para actualizar por lotes, en lugar del modo de actualización automático. Solo puede emplearse con cursores estáticos construidos con las bibliotecas del lado del cliente.
Para poder trabajar con ellos, necesitas de los cursores:
1) AdOpenForwardOnly: De solo avance. Disponible del lado del servidor. Usalo solamente para operaciones de solo lectura.
2)AdOpenStatic: Del lado del cliente. Es difícil explicar como funciona, solo te diré que no te lo recomiendo porque es como tomar una copia estática de resultados.
3) AdOpenKeyset: (MI FAVORITO). Disponible del lado del servidor. Cursor de conjunto de claves igual que un cursor dinámico, excepto porque no es posible ver los registros que añadan otros usuarios. Este de lectura/escritura, totalmente desplazable. Es mucho más económico que el dynamic.
4) AdOpenDynamyc: (TAMBIÉN ES MI FAVORITO, USALO PARA INSERTAR, MODIFICAR, ELIMINAR). Todos los cambios realizados por otro usuarios serán visibles, y están permitidos para todos los desplazamiento de recordset. Es el más costoso, un poco más lento.
Si puedes usar todo el tiempo el keyset, es el mejor...
De todas maneras prueba esto, espero te funcione... si necesitas más información, escríbeme de nuevo. Hasta pronto!
Hola! a ver ... paso a paso para no perderme:
-Los accesos los controlo mediante una tabla de usuarios, pero actualmente, unicamente esta accediendo un usuario a la aplicación.
-Un usuario no puedo modificar o eliminar un registro que esta siendo modificado. Esto lo controlo yo por código, ya que el access no lo hace.
-Si, la aplicación trabaja en una red. Actualmente, son dos ordenadores conectados en red. La base de datos está en uno de ellos (en el que principalmente trabaja con la aplicación, ya que el otro apenas es utilizado).
-Las conexiones que realizo son mediante ADODB
-Te pongo un fragmento de código ...
--O--
Las conexiones las realizo en un modulo.
Public gConexion As ADODB.Connection
Set gConexion = New ADODB.Connection
gConexion.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source = " & BDstr & "BaseDatosTienda.mdb;Persist Security Info=False"
gConexion.Open
----------------------------------
Las inserciones las realizo de la siguiente forma. Simplemente construyo una sql con un "insert into taba (campo1, campo2,...) values (x, y, ...)" y luego ejecuto la instrucción: "gconexion.execute(ssql)"
----------------------------------
Las modificaciones ... realizo una select con la que obtengo el registro deseado de la siguiente forma:
Dim oRS As ADODB.Recordset
Set oRS = New ADODB.Recordset
Set RecSetSer = gConexion.Execute("SELECT CAMPO1,CAMPO2 FROM TABLA WHERE CAMPO3=" & CLNG(DATO))
MUESTRO LOS DATOS EN PANTALLA Y LUEGO REALIZO LAS MODIFICACIONES MEDIANTE UNA SQL TAL QUE ... "UPDATE TABLA SET CAMPO1=" & X & ", CAMPO2 = " & Y & " WHERE CAMPO3 = " & CLNG(DATO)
--O--
Gracias por tu interés, Ana.
-Los accesos los controlo mediante una tabla de usuarios, pero actualmente, unicamente esta accediendo un usuario a la aplicación.
-Un usuario no puedo modificar o eliminar un registro que esta siendo modificado. Esto lo controlo yo por código, ya que el access no lo hace.
-Si, la aplicación trabaja en una red. Actualmente, son dos ordenadores conectados en red. La base de datos está en uno de ellos (en el que principalmente trabaja con la aplicación, ya que el otro apenas es utilizado).
-Las conexiones que realizo son mediante ADODB
-Te pongo un fragmento de código ...
--O--
Las conexiones las realizo en un modulo.
Public gConexion As ADODB.Connection
Set gConexion = New ADODB.Connection
gConexion.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source = " & BDstr & "BaseDatosTienda.mdb;Persist Security Info=False"
gConexion.Open
----------------------------------
Las inserciones las realizo de la siguiente forma. Simplemente construyo una sql con un "insert into taba (campo1, campo2,...) values (x, y, ...)" y luego ejecuto la instrucción: "gconexion.execute(ssql)"
----------------------------------
Las modificaciones ... realizo una select con la que obtengo el registro deseado de la siguiente forma:
Dim oRS As ADODB.Recordset
Set oRS = New ADODB.Recordset
Set RecSetSer = gConexion.Execute("SELECT CAMPO1,CAMPO2 FROM TABLA WHERE CAMPO3=" & CLNG(DATO))
MUESTRO LOS DATOS EN PANTALLA Y LUEGO REALIZO LAS MODIFICACIONES MEDIANTE UNA SQL TAL QUE ... "UPDATE TABLA SET CAMPO1=" & X & ", CAMPO2 = " & Y & " WHERE CAMPO3 = " & CLNG(DATO)
--O--
Gracias por tu interés, Ana.
- Compartir respuesta
- Anónimo
ahora mismo
Respuesta de miguiyluis
1
1
miguiyluis, Ingeniero de Sistemas
En las transacciones existe un contador interno de la transacción, cuando usamos el BEGIN TRAN ese contador se incrementa en una unidad y cuando se realiza un COMMIT TRAN, este lo que hace es disminuir el contador de la transacción en 1 y una transacción solo se guarda cuando cuando este contador llega a 0.
Es decir, que si por lo menos tu tienes don BEGIN TRAN y solo un COMMIT TRAN al final, no se almacenara nada porque el contador esta en 1 y no en 0...
No se si este sea tu caso, si este sea el problema que tienes ya que no he visto tu código para asegurarlo, pero puede que este sea tu problema...
Revisa esta página donde se explica (más claramente) lo que te estoy mencionando del contador...
http://sql.manivesa.com/Tutoriales+SQL/Procedimientos+Almacenados/562.aspx
Cualquier cosa que no sea eso, vuelve a escribir que yo estoy pendiente...
Es decir, que si por lo menos tu tienes don BEGIN TRAN y solo un COMMIT TRAN al final, no se almacenara nada porque el contador esta en 1 y no en 0...
No se si este sea tu caso, si este sea el problema que tienes ya que no he visto tu código para asegurarlo, pero puede que este sea tu problema...
Revisa esta página donde se explica (más claramente) lo que te estoy mencionando del contador...
http://sql.manivesa.com/Tutoriales+SQL/Procedimientos+Almacenados/562.aspx
Cualquier cosa que no sea eso, vuelve a escribir que yo estoy pendiente...
Ya he revisado todos los procedimientos donde se trabaja con transacciones y todos ellos tienen el begintrans (al principio), el commit (al final, si no se ha producido ningún fallo), y el rollbacktrans (si se ha producido algún fallo).
Debes revisar si después de hacer cada una de las operaciones, ya sea agregar o modificar, actualizas tu bd, si lo deseas mandame el código donde haces esto para revisarlo...
Ok, ya lo he leído pero me ha surgido la siguiente duda ... yo hago esto:
Private Sub Insertar()
on error goto FalloIns
oCN.BeginTrans
sQS = "INSERT INTO ..."
oCN.Execute(sQS)
oCN.CommitTrans
Exit Sub
FalloIns:
MsgBox "Se ha producido un error."
oCN.RollBackTrans
End Sub
---> ¿Cómo podría utilizar aquí el SaveTran? ¿O es una instrucción que no se puede utilizar en Visual Basic? Es que lo he probado, y cuando escribo el nombre de la conexión y el punto, no me reconoce el savetran
Private Sub Insertar()
on error goto FalloIns
oCN.BeginTrans
sQS = "INSERT INTO ..."
oCN.Execute(sQS)
oCN.CommitTrans
Exit Sub
FalloIns:
MsgBox "Se ha producido un error."
oCN.RollBackTrans
End Sub
---> ¿Cómo podría utilizar aquí el SaveTran? ¿O es una instrucción que no se puede utilizar en Visual Basic? Es que lo he probado, y cuando escribo el nombre de la conexión y el punto, no me reconoce el savetran
Si se puede utilizar en visual basic...
Revisa esta página de msdn que te explica un poco mejor como funciona el sabe trans dentro de vb6:
http://msdn.microsoft.com/library/spa/default.asp?url=/library/spa/cpref/html/frlrfsystemdatasqlclientsqltransactionclasssavetopic.asp
Revisa esta página de msdn que te explica un poco mejor como funciona el sabe trans dentro de vb6:
http://msdn.microsoft.com/library/spa/default.asp?url=/library/spa/cpref/html/frlrfsystemdatasqlclientsqltransactionclasssavetopic.asp
- Compartir respuesta
- Anónimo
ahora mismo