Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Error "Esta fila ya pertenece a otra tabla"

2,021 views
Skip to first unread message

Juan Bach

unread,
Aug 12, 2008, 5:02:02 AM8/12/08
to
Tengo dos tablas de dos basess de datos diferentes y el codigo siguiente es
el que me da el error al insertar una nueva fila, he leido algo sobre este
error pero utiliza la instrución import, que creo no puedo utilizar yo , ya
que hago un calculo en la tabla.

'Paso los datos de uno de la tabla del PDA a la local
Dim f As Integer, j As Integer, i As Integer, k As Integer
Dim dtLocalID As DataTable
Dim daLocalID As SqlDataAdapter
Dim sSelLocal As String = "SELECT * FROM lecturas "
'Todo esto lo hago para saber la ID y dar el siguiente numero
daLocalID = New SqlDataAdapter(sSelLocal, cnnLocal)
dtLocalID = New DataTable
' Llenar la tabla con los datos indicados
daLocalID.Fill(dtLocalID)
j = dtLocalID.Rows.Count
If j = 0 Then
k = 1
Else
Dim drlocalID As DataRow = dtLocalID.Rows(j - 1)
k = drlocalID("ID") + 1
End If

'Aqui ya trabajo con las dos filas y paso la una a la otra
f = 0
Dim dr As DataRow = dt.Rows(f)

j = dt.Rows.Count

For i = 0 To j - 1
Dim drLocal As DataRow = dtLocal.NewRow()
drLocal("ID") = k + i
drLocal("lec_fecha") = dr("lec_fecha").ToString
drLocal("lec_provee") = dr("lec_provee").ToString
drLocal("lec_cliente") = dr("lec_cliente").ToString
drLocal("lec_nroCanal") = dr("lec_nroCanal").ToString
drLocal("lec_pieza") = dr("lec_pieza").ToString
drLocal("lec_paisnaci") =
buscarPais(dr("lec_paisnaci").ToString)
drLocal("lec_paisengorde") =
buscarPais(dr("lec_paisengorde").ToString)
drLocal("lec_paissacri") =
buscarPais(dr("lec_paissacri").ToString)
drLocal("lec_pais_desp") =
buscarPais(dr("lec_pais_desp").ToString)
drLocal("lec_regmata") = dr("lec_regmata").ToString
drLocal("lec_regdespie") = dr("lec_regdespie").ToString
dtLocal.Rows.Add(drLocal)
If i + 1 < j Then dr = dt.Rows(i + 1)
Next i
'


daLocal.Update(dtLocal)
dtLocal.AcceptChanges()
MessageBox.Show("Traspasados " & j & " registros ", "",
MessageBoxButtons.OK, MessageBoxIcon.Information)
Catch ex As DBConcurrencyException
MessageBox.Show("Error de concurrencia:" & vbCrLf & ex.Message)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try

SoftJaén

unread,
Aug 12, 2008, 7:50:01 AM8/12/08
to
"Juan Bach" escribió:

> Tengo dos tablas de dos basess de datos diferentes y el codigo siguiente
> es el que me da el error al insertar una nueva fila, he leido algo sobre
> este error pero utiliza la instrución import, que creo no puedo utilizar

> yo, ya que hago un calculo en la tabla.

No sé lo que tiene que ver que utilices o no la instrucción «Imports» con la
excepción que estás obteniendo. ¿?

El código que has publicado es bastante complicado de "digerir", porque
aparte de que seguramente no tienes activada la instrucción «Option Strict»,
con lo cual tu código fuente está expuesto a que se produzca cualquier tipo
de excepción, no observo por ninguna parte la declaración que haces de la
variable objeto «dtLocal», que me imagino representa a un objeto DataTable,
pero no sé si la has creado utilizando la palabra clave «New», o has
utilizado el método «Clone» de otro objeto DataTable para clonar la
estructura de éste último objeto.

Si por una casualidad de la vida es ésto último lo que has hecho (utilizar
el método «Clone»), es normal que obtengas la excepción «Esta fila ya
pertenece a otra tabla» cuando utilizas el método «Add» para añadir la fila
al objeto DataTable. Si deseas reproducir el error, no tienes nada más que
ejecutar el siguiente ejemplo:

' Referencio el objeto DataTable enlazado a un control DataGridView
'
Dim dt As DataTable = DirectCast(DataGridView1.DataSource, DataTable)

' Referencio la primera fila del objeto DataTable.
'
Dim dr As DataRow = dt.Rows(0)

' Clono la estructura del objeto DataTable.
'
Dim dt2 As DataTable = dt.Clone

' Intento a¤adir la fila al objeto DataTable.
'
dt2.Rows.Add(dr)

Cuando intentes ejecutar la última sentencia, obtendrás la excepción
comentada. Para poder añadir la fila al objeto DataTable representado por la
variable objeto «dt2», tendrías que añadir la fila utilizando el método
«ImportRow»:

' Copiamos la fila en la nueva DataTable, conservando tanto
' los valores de las propiedades, como los valores originales
' y actuales de la fila u objeto DataRow.
'
dt2.ImportRow(dr)

En fín. No sé si éste será tu caso, pero como te he comentado anteriormente,
observando tu código, no puedo "adivinar" donde se produce el error y a qué
es debido.

Un saludo

--
Enrique Martínez
[MS MVP - VB]

Nota informativa: La información contenida en este mensaje, así como el
código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin
garantías de ninguna clase, y no otorga derecho alguno. Usted asume
cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o
sugerido en el presente mensaje.

Juan Bach

unread,
Aug 18, 2008, 6:46:00 AM8/18/08
to
Gracias como siempre por tu ayuda, estos dias no he podido trabajar en este
asunto y hoy lo retomo. Estas son las variables

Dim sCnnLocal As String
Dim cnnLocal As New SqlConnection(sCnnLocal)
Dim sCnn As String

Dim cnn As New SqlCeConnection

Private dt As DataTable
Private da As SqlCeDataAdapter

Private dtLocal As DataTable
Private daLocal As SqlDataAdapter

Private fila As Integer

El error me da en dtLocal.Rows.Add(drLocal) , creo que no puedo hacer todo
lo que me dices ya que tengo que calcular drLocal("ID") = k + i
Como ves me falta mucho para decir que tengo algo de idea en esto del .net
pero vamos sigo investigando

SoftJaén

unread,
Aug 18, 2008, 11:07:42 AM8/18/08
to
"Juan Bach" escribió:

> Estas son las variables
>
> Private dtLocal As DataTable

Bueno, con esa declaración, ya sé que no has utilizado la palabra clave
«New». Ahora me queda saber si has utilizado el método «Clone» de otro

objeto DataTable para clonar la

estructura del objeto DataTable llamado «dtLocal».

> El error me da en dtLocal.Rows.Add(drLocal) ,

Si las cosas no están bien hechas, en esa sentencia es donde se suele
producir el error que estás obteniendo.

Lo siento, pero me remito a mi anterior mensaje, donde explico cómo
reproducir la excepción y la posible solución.

Juan Bach

unread,
Aug 26, 2008, 5:50:00 AM8/26/08
to
No tengo ningún metodo clone ,como te dije no creo poder utilizarlo ya que
tengo que calcular algún dato.

He declarado asi ahora el datetable pero tampoco van por ahi los tiros
Private dtLocal As New DataTable

No he tenido tiempo pero esta semana creo que si asi que sigo "investigando"

Juan Bach

unread,
Aug 26, 2008, 6:54:06 AM8/26/08
to
Voy a retomar el problema desde 0 ya que veo que mi codigo lo que hace es
complicar la conversación . Tengo una PDA con una serie de lecturas , lo que
hago es leer esa tabla registro por registro y pasarlo a una base de datos
local cambiando algunas cosas por ejemplo el codigo numerico de pais por el
nombre.
¿Como debo afrontar el problema? Es decir, como me planteo mi idea es coger
objetos DataTable (uno por base datos-tabla) y ir leyendo y añadiendo con
DateRow
¿Es correcto el planteamiento?¿Hay alguna forma más facil?
Gracias

SoftJaén

unread,
Aug 26, 2008, 12:57:07 PM8/26/08
to
"Juan Bach" escribió:

A mí de PDA no me hables, porque no dispongo de uno para hacer las
correspondientes pruebas, por tanto, mejor será que hablemos de un PC normal
y corriente, y después las conclusiones que saques las aplicas al PDA. :-)

Dices que en el PDA tienes una serie de lecturas. Esas lecturas, ¿qué son?
¿Una tabla de una base de datos? ¿Un archivo de texto delimitado? ¿Un
archivo de Excel?

También dices que esas lecturas las deseas pasar a una base de datos local,
previa modificación de una serie de datos. ¿Qué tipo de base de datos es la
base de datos local? ¿Access, SQL Server, Oracle?

Para saber si hay una forma más fácil de realizar ese traspaso de datos,
tendré que saber primero qué tipos de archivos estás utilizando.

Lo que sí te puedo decir es que ADO .net te permite cargar los datos (las
lecturas del PDA) en un objeto DataTable, hacer las modificaciones
oportunas, y una vez que esté todo listo, actualizar la base de datos de
destino utilizando el método «Update» de un adaptador de datos apropiado,
por lo que en principio, sólo tendrías que recorrer las filas del objeto
DataTable para efectuar las modificiaciones que creas oportunas:

' Conforme recorremos las filas del objeto DataTable,
' vamos modificando el valor del campo.
'
For Each row As DataRow In dt.Rows
row.Item("NombreCampo") = "NuevoValor"
Next

De esa manera te aseguro que no obtendrás la excepción «Esta fila ya
pertenece a otra tabla».

Para que te hagas una idea, ese objeto DataTable tiene que tener la misma
estructura que la tabla de la base de datos de destino, de ésta manera,
cuando deseas actualizar la base de datos de destino, abres una conexión con
dicha base de datos, configuras adecuadamente el adaptador de datos, y
cuando llames a su método «Update», le pasas el objeto DataTable que has
utilizado para obtener las lecturas del PDA. ¿Me explico?

Esa es la flexibilidad que tiene trabajar con objetos DataSet o DataTable,
ya que estos objetos son independientes de cualquier origen de datos, por lo
que podemos coger los datos de un archivo de texto delimitado, efectuar una
serie de modificaciones, y enviar el resultado a una tabla de una base de
datos de SQL Server. Pero para hacer todo esto de una manera fácil y eficaz,
hay que procurar que el objeto DataTable tenga la misma estructura que la
tabla de la base de datos de destino, y que ésta último tabla, tenga
establecida su correspondiente clave principal, de ésta manera podremos
utilizar un objeto «CommandBuilder» para configurar adecuadamente el
adaptador de datos, de otra manera tendríamos que configurar el adaptador de
datos manualmente, y ésto puede llegar a ser complicado.

En fin, lo mismo hay otra más fácil de transferir los datos, pero como te he
dicho antes, necesito saber los tipos de archivos o bases de datos con los
que estás trabajando.

Juan Bach

unread,
Aug 27, 2008, 10:58:02 AM8/27/08
to
Trabajo con Sql Server Mobile en la Pda y con Sql Server en LOCAL. El tema es
que las tablas de la PDA y la local no tienen la misma estructura , si el
problema es este pues tendre que cambiar la estructura , te agradezco tus
recomendaciones

SoftJaén

unread,
Aug 27, 2008, 11:28:38 AM8/27/08
to
"Juan Bach" escribió:

> Trabajo con Sql Server Mobile en la Pda y con Sql Server en LOCAL. El tema
> es que las tablas de la PDA y la local no tienen la misma estructura , si
> el problema es este pues tendre que cambiar la estructura

Si no te quieres complicar mucho la vida, la estructura del objeto DataTable
intermedio tiene que ser la misma que la tabla de la base de datos local de
SQL Server.

Los pasos a seguir serían:

1º) Cargar los datos de la PDA en un objeto DataTable. Para ello,
necesitarás utilizar un adaptador de datos adecuado que ejecute una consulta
SQL de selección, cuyo orden de columnas deberá ser el mismo que tienen las
columnas en la tabla de la base de datos de destino. Por ejemplo, imagina
que en ésta última base de datos tienes la clásica tabla de Clientes, cuyo
orden de campos son los siguientes:

IdCliente --> Clave principal
Nombre
Campo3
Campo4
Campo5

El adaptador de datos que utilices para rellenar el objeto DataTable,
ejecutaría la siguiente consulta SQL de selección:

Dim sql As String = _
"SELECT IdCliente, Nombre, Campo3, Campo4, Campo5 " & _
"FROM NombreTabla"

2º) Una vez relleno el objeto DataTable, en el mismo objeto haces las
modificaciones oportunas como te expliqué en mi anterior mensaje:

' Conforme recorremos las filas del objeto DataTable,
' vamos modificando el valor del campo.
'

For Each row As DataRow In objetoDataTable.Rows


row.Item("NombreCampo") = "NuevoValor"
Next

3º) Configuras un adaptador de datos para actualizar la tabla de la base de
datos local.

4º) Llamas al método «Update» del adaptador de datos configurado en el paso
anterior, pasándole el objeto DataTable modificado:

Dim n As Int32 = objetoDataAdapter.Update(objetoDataTable)

MessageBox.Show("Nº de registros actualizados: " & CStr(n))

Esos son los pasos que debes seguir para pasar los datos de la PDA a la base
de datos local de SQL Server, previa modificación de los valores de ciertos
campos.

0 new messages