You are on page 1of 17

1. Otros.

Una vez visto los objetos de conexin, vamos a ver una serie de objetos que realizan tambin tareas dentro del acceso a una base de datos. Este objeto tiene como misin el realizar el enlace entre dos objetos que no pueden enlazarse directamente por carecer del recurso adecuado. Normalmente el enlace de un origen de datos y uno de visualizacin se realiza a travs de la propiedad DataSource, pero cuando no se dispone de ella, se puede utilizar este objeto para realizar dicho enlace. El objeto ms utilizado en la visualizacin es el datagridview, este objeto dispone de la propiedad DataSource, por lo que su enlace no representa mayor problema. Primero, proporciona una capa de direccionamiento indirecto al enlazar los controles de un formulario a los datos. Esto se lleva a cabo enlazando el componente BindingSource a su origen de datos y enlazando a continuacin los controles del formulario al componente BindingSource. Todas la dems interaccin con los datos, incluido el desplazamiento, la ordenacin, el filtrado y la actualizacin, se lleva a cabo con llamadas al componente BindingSource. El enlace se lleva a cabo a travs de la propiedad DataBindings. Veamos su utilizacin. Primero los objetos que se van a utilizar. Dim Dim Dim Dim Dim Dim Conexion As New System.Data.OleDb.OleDbConnection Adaptador As New System.Data.OleDb.OleDbDataAdapter Tabla As DataTable = ObjDataSet.Tables("Provincia") EnlaceTabla As New BindingSource Actualizador As New OleDb.OleDbCommandBuilder(Adaptador) CadenaSql As String = "Select * from provincia order by codprov"

1.1 Introduccin.

1.2 BindingSource.

Y adems TextBox, Campo01, que se supone ya en el formulario. Enlace. El enlace se realiza con la propiedad DataBinding del objeto TextBox. Private Sub Enlaces() Campo00.DataBindings.Add("Text", EnlaceTabla, "CodProv") Campo01.DataBindings.Add("Text", EnlaceTabla, "DenomCas") Campo02.DataBindings.Add("Text", EnlaceTabla, "DenomVal") End Sub Los parmetros son ("Text", La propiedad que se va a enlazar, entre comillas, EnlaceTabla, El objeto que se enlaza al TextBox, el que tiene los datos. "CodProv") El nombre del campo en el objeto de origen de los datos, nombre en la tabla. El objeto para poderlo utilizar debe de tener datos, he aqu la carga del mismo. 1

Este ejemplo es con DataSet Private Sub CargaDatos() ObjDataSet.Clear() If Conexion.State = ConnectionState.Closed Then Conexion.Open() Adaptador = New OleDb.OleDbDataAdapter(CadenaSql, Conexion) Adaptador.Fill(ObjDataSet) EnlaceTabla.DataSource = ObjDataSet.Tables(0) ' ("Provincia") Actualizador = New OleDb.OleDbCommandBuilder(Adaptador) Conexion.Close() End Sub El mismo, pero con un DataTable Private Sub CargaDatos() If Conexion.State = ConnectionState.Closed Then Conexion.Open() Adaptador = New OleDb.OleDbDataAdapter(CadenaSql, Conexion) Adaptador.Fill(Tabla) EnlaceTabla.DataSource = Tabla Actualizador = New OleDb.OleDbCommandBuilder(Adaptador) Conexion.Close() End Sub Podemos borrar el elemento actual de la tabla, registro actual en el formulario.. EnlaceTabla.RemoveCurrent() Iniciar los objetos de TextBox en blanco para aadir un nuevo registro. EnlaceTabla.AddNew() Una vez que se cumplimentan los datos, si quiere grabarse ha de ejecutarse el mtodo EnlaceTabla.EndEdit. Este objeto adems permite realizar tareas de navegacin, con los mtodos que observamos en el ejemplo. EnlaceTabla.MoveFirst() EnlaceTabla.MovePrevious() EnlaceTabla.MoveNext() EnlaceTabla.MoveLast() Y el proceso de actualizacin es el que sigue. Private Sub Actualizar() Conexion.Open() Try Adaptador.Update(CType(EnlaceTabla.DataSource, DataTable)) MsgBox("Datos actualizados.", MsgBoxStyle.Information, Me.Text) Catch ex As OleDb.OleDbException MsgBox("Datos existentes", MsgBoxStyle.Critical, Me.Text) End Try Conexion.Close() End Sub

La actualizacin debe de arrancar, puede, del evento clic de un button, en el que se ejecuta: EnlaceTabla.EndEdit() Actualizar() La primera lnea finaliza la edicin del registro que se aadi nuevo, o que se estaba editando. La segunda llama al procedimiento de actualizacin. Si deseamos cancelar los cambios que se hayan hecho en el registro actual, podemos ejecutar EnlaceTabla.CancelEdit() Y los cambios en el registro actual se desharn. Todo lo referente al objeto BindingSource podemos encontrarlo en el siguiente Link. http://msdn2.microsoft.com/es-es/library/system.windows.forms.bindingsource(VS.80).aspx

Es un objeto que genera de forma automtica el cdigo SQL necesario para proceder a la actualizacin de una tabla de la base de datos. No es posible utilizarlo para las tablas que se generen de forma provisional, pues ests tablas suelen estar compuestas por datos de varias tablas, o para tablas en las que los datos a aadir son una coleccin de varios registros. La utilizacin es relativamente sencilla. En un DataSet el objeto OleDbCommandBuilder puede ser reutilizado y no es necesario tener uno para cada tabla del DataSet. Va asociado con un objeto DataTable y un DataAdapter, pues el conjunto permite la gestin de los datos. El ejemplo que sigue carga los datos en un DataGridView, y lo deja enlazado a la tabla, de tal forma que con muy poco ms es suficiente para la visualizacin y la edicin de los datos de la tabla. La utilizacin del CommandBuilder es como sigue: Dim ComandoActualizar As OleDb.OleDbCommandBuilder A continuacin su asignacin, no debe moverse del sitio pues sino no dispone de la informacin necesaria para generar el cdigo SQL ' Crear un 'commandbuilder' que genere el SQL Update/Insert/Delete ComandoActualizar = New OleDb.OleDbCommandBuilder(Adaptador) Y el procedimiento completo es el que sigue, para poder tener una visin algo ms amplia. Public Sub CargaDataGrid( _ ByVal Conexion As System.Data.OleDb.OleDbConnection, _ ByRef Adaptador As System.Data.OleDb.OleDbDataAdapter, _ ByRef EnlaceTabla As BindingSource, _ ByRef ObjDataGrid As DataGridView, _ ByVal CadenaSql As String) Dim ComandoActualizar As OleDb.OleDbCommandBuilder Dim Tabla As New DataTable Try ' Crear un nuevo adaptador de datos Adaptador = New OleDb.OleDbDataAdapter(CadenaSql, Conexion) ' Crear un 'commandbuilder' que genere el SQL Update/Insert/Delete ComandoActualizar = New OleDb.OleDbCommandBuilder(Adaptador) 3

1.3 CommandBuilder.

' Llenar la tabla Adaptador.Fill(Tabla) ' Enlazar la tabla ObjDataGrid.DataSource = Tabla Catch ex As OleDb.OleDbException MsgBox(ex.Message, MsgBoxStyle.Information) End Try End Sub Si en lugar de utilizarlo en un DataTable, se usa en una tabla dentro de un DataSet, no hay cambio alguno, pues el objeto funciona a nivel de DataTable, no de DataSet, por lo que no hay ningn cambio en su utilizacin, la definicin y el uso es exactamente igual. Todo lo referente al objeto OleDbCommandBuilder podemos encontrarlo en el siguiente Link. http://msdn2.microsoft.com/es-es/library/system.data.oledb.oledbcommandbuilder(VS.80).aspx Nos permite realizar diversos tipos de operaciones con la base de datos. Almacena bsicamente el cdigo SQL para interactuar con la base de datos, pero dispone de varias funcionalidades. En el ejemplo que sigue se usa en la generacin de un objeto DataReader para cargar un ListBox con una consulta incrustada. Su definicin es Dim Comando As New System.Data.OleDb.OleDbCommand Despus primero le asignamos el cdigo SQL ' Contenido del comando Comando.CommandText = CadenaSQL Despus le indicamos de que tipo es el cdigo SQL que se le asigna, una cadena de texto, o una consulta almacenada, en el ejemplo le indicamos que es una cadena de texto. ' Tipo de comando a ejecutar Comando.CommandType = CommandType.Text Y el siguiente paso es asignarle el origen de datos que se va a utilizar. ' Conexin a utilizar, configurada previamente. Comando.Connection = Conexion Pasada la fase de definicin, se ejecuta el cdigo SQL, asignando el resultado de su ejecucin a un objeto DataReader. ' Ejecucin de SQL Reader = Comando.ExecuteReader En este caso se ha usado el mtodo ExecuteReader, pero disponemos de otra faceta, para cuando no hay que devolver datos, ExecuteNonQuery, para las instrucciones Update, Delete por ejemplo.

1.4 Command.

Veamos el procedimiento completo. Public Sub CargaListaAutores( _ ByRef Lista As ListBox, _ ByVal Conexion As System.Data.OleDb.OleDbConnection) Dim CadenaSQL As String Dim Comando As New System.Data.OleDb.OleDbCommand Dim Reader As System.Data.OleDb.OleDbDataReader Dim Objeto As ItemLista Lista.Items.Clear() CadenaSQL = "Select Codigo, Nombre " & _ "From Autores " & _ "Order By Nombre" Try ' Abrir la base de datos. Conexion.Open() ' Contenido del comando Comando.CommandText = CadenaSQL ' Tipo de comanndo a ejecutar Comando.CommandType = CommandType.Text ' Conexin a utilizar, configurada previamente. Comando.Connection = Conexion ' Ejecucin de SQL Reader = Comando.ExecuteReader Try While Reader.Read Objeto = New ItemLista(Trim(Reader.Item("Nombre").ToString), _ Reader.Item("Codigo").ToString) Lista.Items.Add(Objeto) End While Catch ex As OleDb.OleDbException MsgBox(ex.Message, MsgBoxStyle.Information, "Leer reader") End Try Catch Ex As OleDb.OleDbException MsgBox(Ex.Message, MsgBoxStyle.Information, "Crear reader") End Try Conexion.Close() End Sub Si en lugar de utilizar una cadena SQL, usamos una consulta almacenada en la base de datos, en este caso en Access, los cambios son estos. ' Nombre de la consulta en la base de datos. Comando.CommandText = "Usp_UpdateProvincia" ' Tipo de comando a ejecutar Comando.CommandType = CommandType.StoredProcedure ' Conexin a utilizar, configurada previamente. Comando.Connection = Conexion Hay que pensar que el resto es el mismo, solo se ha cambiado la fuente del cdigo SQL, que ahora est almacenado en la base de datos, y cuando la abra lo capturar.

La consulta puede ser que incorpore parmetros, como es el caso del ejemplo que se actualizan datos en la tabla, en ese caso hay que aadir el valor de los parmetros. ' Aadir parmetros de la consulta a ejecutar. Comando.Parameters.Add("@Cod", OleDb.OleDbType.Char, 2).Value = Campo01.Text Comando.Parameters.Add("@DeC", OleDb.OleDbType.Char, 11).Value = Campo02.Text Comando.Parameters.Add("@DeV", OleDb.OleDbType.Char, 11).Value = Campo03.Text El significado de los parmetros es el que sigue. "@Cod", Es el nombre del parmetro en la consulta almacenada. OleDb.OleDbType.Char, 2) Es el tipo de dato que se enva, texto de dos caracteres de longitud. .Value = Campo01.Text Es la forma de darle el valor que se ha de grabar en la base de datos. El cdigo SQL en la consulta que est almacenada en Access es. UPDATE Provincia SET Provincia.CodProv = @Cod, Provincia.DenomCas = @DeC, Provincia.DenomVal = @DeV WHERE (((Provincia.CodProv)=[@Codigo])); Otro ejemplo del uso del Command es el que sigue. La definicin es la misma y la parametrizacin tambin. Dim Comando As New System.Data.OleDb.OleDbCommand ' cdigo SQL a utilizar Comando.CommandText = CadenaSQL ' Tipo de comanndo a ejecutar Comando.CommandType = CommandType.Text ' Conexin a utilizar, configurada previamente. Comando.Connection = Conexion El cambio viene a la hora de la ejecucin que como no devuelve datos, se usa otro mtodo. Cuantos = Comando.ExecuteNonQuery Cuantos es una variable entera que recibe cuantos registros han sido afectados por la ejecucin en ste caso ser uno correcto y cero error. Por eso la variable Fallo ser true cuando Cuantos valga cero. Este es el procedimiento completo. Private Sub GrabarMovimiento( _ ByVal Conexion As System.Data.OleDb.OleDbConnection, _ ByRef Comando As System.Data.OleDb.OleDbCommand, _ ByVal Fech As String, _ ByVal Edit As String, _ ByVal TipT As String, _ ByVal Titu As String, _ ByVal Cant As String, _ ByRef Fallo As Boolean)

Dim Dim Dim Dim Dim

Cuantos As Integer TiMv As String = "1" ' entradas de almacen Nume As String = Campo01.Text Docu As String = Campo02.Text CadenaSQL As String

CadenaSQL = "INSERT INTO

Movimientos ( Fecha, Tipo, Codigo, " & _ "TipTitulo, Titulo, TipMov, Cantidad, " & _ "FacAbo, Numero ) " & _ "Values ('" & Fech & "', " & _ "'" & Edit & "', " & _ "'" & Docu & "', " & _ "'" & TipT & "', " & _ "'" & Titu & "', " & _ "'" & TiMv & "', " & _ "'" & Cant & "', " & _ "'0', " & _ "'" & Nume & "') " ' cdigo SQL a utilizar Comando.CommandText = CadenaSQL ' Tipo de comando a ejecutar Comando.CommandType = CommandType.Text ' Conexin a utilizar, configurada previamente. Comando.Connection = Conexion Try Cuantos = Comando.ExecuteNonQuery Fallo = Cuantos = 0 Catch ex As OleDb.OleDbException Fallo = True MsgBox(ex.Message, MsgBoxStyle.Information) End Try End Sub Todo lo referente al objeto Command podemos encontrarlo en el siguiente Link. http://msdn2.microsoft.com/es-es/library/system.data.oledb.oledbcommand(VS.80).aspx

Este objeto permite obtener datos de una tabla a partir de unos criterios definidos. Tiene la caracterstica que permite seleccionar las filas de una tabla que hayan sido modificadas, borradas o insertadas, siempre que no se haya hecho el volcado o la actualizacin de los datos en la base de datos. Tambin se puede indicar porque campo queremos que nos ordene los datos que se van a filtrar. Los pasos son: Asignar la tabla origen de la informacin. ' Asignacin de la tabla ObjDataView.Table = Tabla Si deseramos modificar el contenido de la vista, cambiaramos a true estos valores. ' No se permite edicin. ObjDataView.AllowDelete = False ObjDataView.AllowEdit = False ObjDataView.AllowNew = False

1.5 DataView.

Indicar el contenido del campo a utilizar en el filtro. ' campo a usar en el filtro. ObjDataView.RowFilter = "Tipo = '" & Tipo & "'" Que filas deseamos visualizar, se puede seleccionar, entre las actuales, solo borradas, insertadas, etc. ' Cuales ObjDataView.RowStateFilter = DataViewRowState.CurrentRows El campo por el cual queremos la ordenacin. ' campo a usar para la ordenacin ObjDataView.Sort = "RazonSocial" Despus solo queda recorrer el objeto para capturar el resultado del filtrado. For X = 0 To ObjDataView.Count - 1 Objeto = _ New ItemLista(Trim(ObjDataView(X).Row.Item("RazonSocial").ToString), _ ObjDataView(X).Row.Item("Tipo").ToString, _ ObjDataView(X).Row.Item("Codigo").ToString) Lista.Items.Add(Objeto) Next El cdigo completo es el que sigue. Public Sub CargaListaClientesDS(ByVal Tabla As DataTable, _ ByRef Lista As ListBox, _ ByVal Tipo As String) Dim X As Integer Dim Objeto As ItemLista Dim ObjDataView As DataView ' Crear el objeto ObjDataView = New DataView(Tabla) ' Definir parmetros With ObjDataView ' Asignacin de la tabla .Table = Tabla ' No se permite edicin. .AllowDelete = False .AllowEdit = False .AllowNew = False ' campo a usar en el filtro .RowFilter = "Tipo = '" & Tipo & "'" .RowStateFilter = DataViewRowState.CurrentRows ' campo a usar para la ordenacin .Sort = "RazonSocial" End With Lista.Items.Clear() For X = 0 To ObjDataView.Count - 1 Objeto = _ New ItemLista(Trim(ObjDataView(X).Row.Item("RazonSocial").ToString), _ ObjDataView(X).Row.Item("Tipo").ToString, _ ObjDataView(X).Row.Item("Codigo").ToString) Lista.Items.Add(Objeto) Next End Sub

Todo lo referente a este objeto lo podemos encontrar en el siguiente Link. http://msdn2.microsoft.com/es-es/library/system.data.dataview(VS.80).aspx

1.6 DataRelation.

Este objeto permite definir las relaciones dentro de un DataSet. Su utilizacin es como sigue. Private Sub CrearRelacion() ' ' Crear relaciones ' ObjDataSet.Relations.Clear() Dim RelGruAlu As DataRelation = _ ObjDataSet.Relations.Add("GrupoAlumno", _ ObjDataSet.Tables("Grupos").Columns("CodGrupo"), _ ObjDataSet.Tables("Alumnos").Columns("Grupo")) Dim RelAluAsi As DataRelation = _ ObjDataSet.Relations.Add("AlumnosAsignaturas", _ ObjDataSet.Tables("Alumnos").Columns("Exped"), _ ObjDataSet.Tables("AlumnAsig").Columns("Exped")) End Sub Donde ObjDataSet.Relations.Add("GrupoAlumno", _ es el nombre de la relacin dentro del DataSet. ObjDataSet.Tables("Grupos").Columns("CodGrupo"), _ es el campo de la tabla principal, Grupos. ObjDataSet.Tables("Alumnos").Columns("Grupo")) es el campo en la tabla secundaria, Alumnos.

Se pueden aadir las relaciones necesarias para el control del DataSet. Cuando se aade una relacin, se comprueba que est se cumple y si no es as se genera un error. Como se puede observar es para el DataSet, pero en la base de datos tendremos definidas las relaciones de integridad para la gestin de la misma. Con esas relaciones definidas para una tarea de mantenimiento realizada fuera de un DataSet, es suficiente, ya que con declararlas como no eliminar en cascada, a la hora de intentar borrar un registro con datos dependientes se genera un error que se puede capturar con el Try Catch del tipo OleDbException. Vemos un ejemplo en el que se borra un registro en la tabla, sin que haya ningn cdigo en concreto para la gestin de una relacin. Los pasos son : Generar el cdigo SQL, Asignar los parmetros del objeto OleDbCommand, Ejecutar el cdigo SQL Controlar los errores

Podemos ver el procedimiento completo. Private Sub Borrar() Dim Comando As New System.Data.OleDb.OleDbCommand Dim Cuantos As Integer Dim CadenaSQl As String CadenaSQl = "Delete From Editoriales " & _ "Where (Editoriales.Codigo = '" & Campo01.Text & "');" Conexion.Open() ' Nombre de la consulta en la base de datos. Comando.CommandText = CadenaSQl ' Tipo de comando a ejecutar Comando.CommandType = CommandType.Text ' Conexin a utilizar, configurada previamente. Comando.Connection = Conexion Try Cuantos = Comando.ExecuteNonQuery Select Case Cuantos Case Is <> 0 MsgBox("Datos borrados", MsgBoxStyle.Information, Me.Text) Case Else ' cuando hay error salta el Catch, y sino MsgBox("Error en borrado", MsgBoxStyle.Information, Me.Text) End Select Catch ex As OleDb.OleDbException MsgBox(ex.Message, MsgBoxStyle.Information, "Error en insercin") End Try Conexion.Close() ' Liberar recursos Comando.Dispose() Comando = Nothing End Sub Podemos ver la ventana con las propiedades de una relacin entre dos tablas, conviene hacer hincapi en el apartado de no activar la opcin de eliminar en cascada, de esa forma podemos evitar algn que otro disgusto. Con esos pasos es suficiente para la gestin de la relacin.

En un DataSet el uso de relaciones mejora la visualizacin de los datos, con el DataGrid, por ejemplo, ya que se realiza prcticamente una navegacin entre los datos origen y los dependientes. Solo es asignar el DataSet al DataGrid.

10

Todo lo referente al DataRelatin lo podemos encontrar en. http://msdn2.microsoft.com/es-es/library/system.data.datarelation(VS.80).aspx

Representa la restriccin de una accin impuesta a un conjunto de columnas en una relacin entre clave principal y clave externa cuando se elimina o actualiza un valor o una fila. Paso a paso, con una tabla de campo nico. Declarar los objetos que vamos a utilizar. ' Declarar las columnas de las relaciones para las restriciones Dim ColPrincipal As DataColumn Dim ColSecundaria As DataColumn Dim Restriccion As ForeignKeyConstraint Eliminar anteriores restricciones. ObjDataSet.Tables("Grupos").Constraints.Clear() Definir las columnas, campos que interviene en la relacin de las tablas. ' Establecer los parmetros, grupos alumnos ColPrincipal = ObjDataSet.Tables("Grupos").Columns("CodGrupo") ColSecundaria = ObjDataSet.Tables("Alumnos").Columns("Grupo") Crear la restriccin. Restriccion = New ForeignKeyConstraint("RestGrupoAlumno", _ ColPrincipal, _ ColSecundaria) Definir las condiciones en borrado, actualizacin. ' Establecer condiciones de la restriccin Restriccion.DeleteRule = Rule.Cascade Restriccion.UpdateRule = Rule.Cascade Restriccion.AcceptRejectRule = AcceptRejectRule.Cascade Aadir la restriccin a las tablas. ' Aadir la restriccin ObjDataSet.Tables("Alumnos").Constraints.Add(Restriccion) Una vez creada la restriccin, hay que marcar su utilizacin. ' Establecer a True la propiedad EnforceConstraints, ' forzar las restricciones. ObjDataSet.EnforceConstraints = True

1.7 Restriction.

11

El ejemplo completo queda como sigue. Private Sub CrearRestriccion() ' Declarar las columnas de las relaciones para las restriciones Dim ColPrincipal As DataColumn Dim ColSecundaria As DataColumn Dim Restriccion As ForeignKeyConstraint ObjDataSet.Tables("Grupos").Constraints.Clear() ' Establecer los parmetros, grupos alumnos ColPrincipal = ObjDataSet.Tables("Grupos").Columns("CodGrupo") ColSecundaria = ObjDataSet.Tables("Alumnos").Columns("Grupo") Restriccion = New ForeignKeyConstraint("RestGrupoAlumno", _ ColPrincipal, _ ColSecundaria) ' Establecer condiciones de la restriccin Restriccion.DeleteRule = Rule.Cascade Restriccion.UpdateRule = Rule.Cascade Restriccion.AcceptRejectRule = AcceptRejectRule.Cascade ' Aadir la restriccin ObjDataSet.Tables("Alumnos").Constraints.Add(Restriccion) ' Aadir la restriccin ObjDataSet.Tables("AlumnAsig").Constraints.Add(Restriccion) ' Establecer a True la propiedad EnforceConstraints, ' forzar las restricciones. ObjDataSet.EnforceConstraints = True End Sub El ejemplo anterior es con un solo campo en la clave. El siguiente es con tablas de varios campos en su clave principal. Private Sub CrearRestriccion() ' Declarar las columnas de las relaciones para las restriciones Dim ColPri(3) As DataColumn Dim ColSec(3) As DataColumn Dim Restriccion As ForeignKeyConstraint ' Establecer los parmetros, asignaturas con asignaturas de alumnos ColPri(0) = ObjDataSet.Tables("Areas").Columns("CodNiv") ColPri(1) = ObjDataSet.Tables("Areas").Columns("CodEtapa") ColPri(2) = ObjDataSet.Tables("Areas").Columns("CodFam") ColPri(3) = ObjDataSet.Tables("Areas").Columns("CodArea") ColPri(0) ColPri(1) ColPri(2) ColPri(3) = = = = ObjDataSet.Tables("AlumnAsig").Columns("Nivel") ObjDataSet.Tables("AlumnAsig").Columns("Etapa") ObjDataSet.Tables("AlumnAsig").Columns("Familia") ObjDataSet.Tables("AlumnAsig").Columns("CodAsig")

Restriccion = New ForeignKeyConstraint("RestAlumAsigAreas", _ ColPri(3), _ ColSec(3)

12

' Establecer condiciones de la restriccin Restriccion.DeleteRule = Rule.Cascade Restriccion.UpdateRule = Rule.Cascade Restriccion.AcceptRejectRule = AcceptRejectRule.Cascade ' Aadir la restriccin ObjDataSet.Tables("AlumnAsig").Constraints.Add(Restriccion) ' Establecer a True la propiedad EnforceConstraints, ' forzar las restricciones. ObjDataSet.EnforceConstraints = True End Sub Todo lo referente al objeto lo podemos encontrar en el link: http://msdn2.microsoft.com/es-es/library/system.data.foreignkeyconstraint(VS.80).aspx

El uso de las tablas conlleva la gestin de los registros y el control de las duplicidades y la localizacin de los datos, para ello se hace necesario el uso de clave principal. Hay dos caminos para conseguirlo, uno es capturarlas de la base de datos, y el otro generarlas. Para las tablas existentes en la base de datos, lo suyo es capturarlo, OleDbDataAdpater.FillSchema, es el mtodo. Para las que se crean de forma provisional en el programa hay que crearlas. Veamos los dos sistemas. La captura de las claves de la tabla es sencilla. Try ObjDataSet.Tables("Titulos").Rows.Clear() ' limpia la tabla Catch ex As NullReferenceException Finally ' LLenar el adaptador Adaptador.Fill(Tabla) ' Capturar la clave desde la tabla Adaptador.FillSchema(Tabla, SchemaType.Source) End Try Solo queda comentar que es la ejecucin de la lnea con el mtodo FillSchema. Su utilizacin posteriormente puede ser como sigue en el ejemplo, en el cual se utiliza para realizar la actualizacin del campo de entradas acumuladas. La explicacin es : Creamos el array para la clave, es una clave de dos campos. Dim Clave(1) As Object Asignamos los datos al array. Clave(0) = CType(Fila.Item("Tipo"), Object) Clave(1) = CType(Fila.Item("Codigo"), Object) Creamos un objeto DataRow para capturar el registro existente con el mtodo Find. Dim Registro As System.Data.DataRow Registro = ObjDataSet.Tables("Titulos").Rows.Find(Clave)

1.8 Definicin de claves.

13

Si se encuentra se actualiza el dato, para ello se utiliza el valor del ndice del registro ledo. If Not (Registro Is Nothing) Then Cual = ObjDataSet.Tables("Titulos").Rows.IndexOf(Registro) SalAcu = CLng(Registro.Item("SalAcu").ToString) SalAcu = SalAcu + CLng(Fila.Item("Cantidad").ToString) ObjDataSet.Tables("Titulos").Rows(Cual).Item("Salacu") = SalAcu End If Y el cdigo completo. Private Sub ActualizarStock(ByVal Fila As DataRow) Dim Clave(1) As Object Dim SalAcu As Long Dim Cual As Integer Clave(0) = CType(Fila.Item("Tipo"), Object) Clave(1) = CType(Fila.Item("Codigo"), Object) Dim Registro As System.Data.DataRow Registro = ObjDataSet.Tables("Titulos").Rows.Find(Clave) Try If Not (Registro Is Nothing) Then Cual = ObjDataSet.Tables("Titulos").Rows.IndexOf(Registro) SalAcu = CLng(Registro.Item("SalAcu").ToString) SalAcu = SalAcu + CLng(Fila.Item("Cantidad").ToString) ObjDataSet.Tables("Titulos").Rows(Cual).Item("Salacu") = SalAcu End If Catch ex As OleDb.OleDbException MsgBox(ex.Message, MsgBoxStyle.Information, _ "Error en actualizacin stocks") End Try End Sub La definicin de una clave principal se realiza as, restriccin de valor nico llamado en VB. Se define el array y la clave. Dim ColPri(1) As DataColumn Dim Clave As UniqueConstraint se le asigna los valores pertinentes. ColPri(0) = Tabla.Columns("Tipo") ColPri(1) = Tabla.Columns("Codigo") se crea el objeto Clave, con el nombre Principal, indicando que es clave principal, ,True). Clave = New UniqueConstraint("Principal", ColPri, True) Se aade a la tabla. Tabla.Constraints.Add(Clave)

14

Y todo completo queda. Private Sub CrearClave(ByVal Tabla As System.Data.DataTable) Dim ColPri(1) As DataColumn Dim Clave As UniqueConstraint ColPri(0) = Tabla.Columns("Tipo") ColPri(1) = Tabla.Columns("Codigo") Clave = New UniqueConstraint("Principal", ColPri, True) Tabla.Constraints.Add(Clave) End Sub Lo referente a UniqueConstraint se puede acceder desde http://msdn2.microsoft.com/es-es/library/system.data.uniqueconstraint(VS.80).aspx

Es el objeto que nos va a permitir realizar los procesos de actualizacin con la seguridad de poder mantener la integridad de la base de datos. La definicin y utilizacin del mismo es como sigue. ' Definicin del objeto Dim Transaccion As System.Data.OleDb.OleDbTransaction ' Inicio de la transaccin Transaccion = Conexion.BeginTransaction(IsolationLevel.Chaos) ' Final correcto de la transaccin Transaccion.Commit() ' Final por error de la transaccin, abortar. Transaccion.Rollback() Solo queda integrar cada instruccin en el punto adecuado del programa. Cuando el proceso de transaccin est en marcha, se ha de tener en cuenta no lanzarlo para un proceso muy amplio, si no en unidades lgicas de actualizacin, no para un programa completo vamos. Como el proceso de actualizacin se ejecuta para varias tablas, cada una de esas tablas se actualiza con su DataAdapter, y en cada uno de esos procesos de actualizacin es necesario la presencia de un objeto OleDbCommand, el objeto OleDbCommand necesita que se le pase el objeto Transaccin que estemos utilizando en ese momento, por lo tanto el uso del objeto OleDbCommand quedara como sigue: ' Cadena SQL Comando.CommandText = CadenaSQL ' Tipo de comando a ejecutar Comando.CommandType = CommandType.Text ' Conexin a utilizar, configurada previamente. Comando.Connection = Conexin ' Asignacin del objeto transaccin en curso. Comando.Transaction = Transaccion Por lo tanto en el procedimiento de actualizacin de cada una de las tablas del programa hay que hacer el cambio o que est presente ' Asignacin del objeto transaccin en curso. Comando.Transaction = Transaccion para su correcto funcionamiento. El ejemplo que sigue empieza comprobando si hay cambios en el DataSet.

1.9 Transaccin.

15

If ObjDataSet.HasChanges Then Despus si es as, se entra en el proceso de actualizar. Se inicia la transaccin. Conexion.Open() ' Inicio de la transaccin Transaccion = Conexion.BeginTransaction(IsolationLevel.Chaos) Se asigna cada OleDbCommand con el objeto conexin y con la transaccin. Comando.Connection = Conexion Comando.Transaction = Transaccion Se capturan los cambios en el DataSet copindolos a un nuevo DataSet, en el ejemplo todos, modificados, borrados e insertados. ObjDataSetCamb = ObjDataSet.GetChanges(DataRowState.Modified _ Or DataRowState.Added _ Or DataRowState.Deleted) Despus se repite tabla a tabla el proceso de actualizacin. Try AdapTitul.Update(ObjDataSetCamb.Tables("Titulos").GetChanges) ObjDataSet.Merge(ObjDataSet.Tables("Titulos")) ObjDataSet.AcceptChanges() Catch ex As ArgumentNullException Fallo = True End Try Hasta llegar al final en el que se comprueba como ha ido, y se confirma o se aborta la transaccin. If Not Fallo Then ' Final correcto de la transaccin Transaccion.Commit() MsgBox("Base actualizada.", MsgBoxStyle.Information, _ "Actualizando dataset") Else ' Final por error de la transaccin Transaccion.Rollback() MsgBox("Actualizacin abortada.", MsgBoxStyle.Critical, _ "Actualizando dataset") End If

16

El ejemplo es completo: Private Sub ActualizarBaseDatos(ByVal Fallo As Boolean) Dim Transaccion As System.Data.OleDb.OleDbTransaction Try Dim ObjDataSetCamb As New DataSet If ObjDataSet.HasChanges Then Conexion.Open() ' Inicio de la transaccin Transaccion = Conexion.BeginTransaction(IsolationLevel.Chaos) Comando.Connection = Conexion Comando.Transaction = Transaccion ComTiTi.Connection = Conexion ComTiTi.Transaction = Transaccion ComTitu.Connection = Conexion ComTitu.Transaction = Transaccion ComMovi.Connection = Conexion ComMovi.Transaction = Transaccion ObjDataSetCamb = ObjDataSet.GetChanges(DataRowState.Modified _ Or DataRowState.Added _ Or DataRowState.Deleted) Try AdapTitul.Update(ObjDataSetCamb.Tables("Titulos").GetChanges) ObjDataSet.Merge(ObjDataSet.Tables("Titulos")) ObjDataSet.AcceptChanges() Catch ex As ArgumentNullException Fallo = True End Try If Not Fallo Then Try AdapMovim.Update(ObjDataSetCamb.Tables("Movimientos").GetChanges) ObjDataSet.Merge(ObjDataSet.Tables("Movimientos")) ObjDataSet.AcceptChanges() Catch ex As ArgumentNullException Fallo = True End Try End If If Not Fallo Then ' Final correcto de la transaccin Transaccion.Commit() MsgBox("Base actualizada.", MsgBoxStyle.Information,Actualizar") Else ' Final por error de la transaccin Transaccion.Rollback() MsgBox("Actualizacin abortada.", MsgBoxStyle.Critical, "Actualizar") End If Conexion.Close() Else MsgBox("No se han realizado cambios", MsgBoxStyle.Information, _ "Actualizando dataset") End If Catch ex As System.Data.OleDb.OleDbException MsgBox(ex.Message, MsgBoxStyle.Information, "Actualizando dataset") End Try End Sub Todo lo referente al objeto lo podemos encontrar en el link: http://msdn2.microsoft.com/es-es/library/system.transactions.transaction(VS.80).aspx

17

You might also like