Parametros Sql y @oldvalue ado.net

Martin Ferrer
24 de Enero del 2015

Hola, tengo un problema, estoy probando un codigo que lo que hace es llenar un dataset, esto en el evento Load. Pero luego, en button1_click necesito comparar los valores viejos de la base de datos con los valores nuevos. Para saber si estos registros que cargue en form1_load cambiaron luego cuando hago button1_click, el problema esta en que no se como hacer que @oldnombre y @oldapallido tome cada uno de los diferentes valores de los diferentes registros del conjunto de datos. Gracias

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Try
connetionString = "PROVIDER=Microsoft.ACE.OLEDB.12.0;Data Source=C:concurrenciabase.accdb;"
connection = New OleDbConnection(connetionString)
connection.Open()
adapter = New OleDbDataAdapter("SELECT * from tabla2", connection)
adapter.Fill(DataSet, "tabla2")



Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub




Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Try
Dim comando As OleDbCommand = connection.CreateCommand()

adapter.UpdateCommand = New OleDbCommand("UPDATE tabla2 set nombre=@nombre, apellido=@apellido WHERE nombre=@oldnombre AND apellido=@oldapellido", connection)

adapter.UpdateCommand.Parameters.Add("@nombre", OleDbType.VarChar, 255).Value = txtID.Text
adapter.UpdateCommand.Parameters.Add("@apellido", OleDbType.VarChar, 255).Value = txtCharData.Text




parameter = adapter.UpdateCommand.Parameters.Add("@oldnombre", OleDbType.VarChar, 255, "nombre")
parameter.SourceVersion = DataRowVersion.Original


parameter = adapter.UpdateCommand.Parameters.Add("@oldapellido", OleDbType.VarChar, 255, "apellido")
parameter.SourceVersion = DataRowVersion.Original



AddHandler adapter.RowUpdated, New OleDbRowUpdatedEventHandler(AddressOf OnRowUpdated)


adapter.Update(dataset, "tabla2")

connection.Close()

End Sub



Sub OnRowUpdated(ByVal sender As Object, ByVal args As OleDbRowUpdatedEventArgs)
If args.RecordsAffected = 0 Then
args.Row.RowError = "Violacion concurrencia optimista"
args.Status = UpdateStatus.SkipCurrentRow
End If
End Sub

End Class


David Carrero
12 de Agosto del 2026

Hola,

La forma más directa de comparar valores viejos contra nuevos en ADO.NET es dejar que sea el propio DataTable el que lleve la cuenta, en vez de guardar tú una copia manual. Cuando cargas el DataSet en el Load, cada fila queda marcada internamente con un RowState (Unchanged al principio). En cuanto el usuario modifica un valor en pantalla y esos cambios se reflejan en el DataTable, el RowState de esa fila pasa automáticamente a Modified, y ADO.NET guarda internamente tanto el valor original como el actual.

En el button1_click, en vez de comparar tú a mano, puedes preguntar directamente qué filas cambiaron:

DataTable cambios = miDataSet.Tables["MiTabla"].GetChanges(DataRowState.Modified);

if (cambios != null) {
    foreach (DataRow fila in cambios.Rows) {
        object valorOriginal = fila["columna", DataRowVersion.Original];
        object valorActual = fila["columna", DataRowVersion.Current];

        Console.WriteLine("Antes: " + valorOriginal + " / Ahora: " + valorActual);
    }
}

GetChanges(DataRowState.Modified) te devuelve un DataTable nuevo que solo contiene las filas que cambiaron desde la carga original, sin tener que recorrer toda la tabla comparando manualmente. Y con el indexador fila["columna", DataRowVersion.Original] accedes al valor tal y como estaba cuando se cargó en el Load, aunque ya lo hayas sobreescrito en pantalla.

El requisito para que esto funcione es que la carga de datos en el Load se haga a través del propio DataAdapter.Fill() sobre el DataSet, y que las modificaciones posteriores se hagan sobre esas mismas filas (por ejemplo, con DataBindings a controles del formulario), no reemplazando el DataSet entero. Si haces eso, no necesitas guardar tú ninguna copia manual de los valores antiguos, ADO.NET ya lo hace por ti.

David Carrero