1. Otros. 1.1 Introducción. 1.2 BindingSource.

Anuncio
1. Otros.
1.1 Introducción.
Una vez visto los objetos de conexión, vamos a ver una serie de objetos que realizan también tareas
dentro del acceso a una base de datos.
1.2 BindingSource.
Este objeto tiene como misión 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 visualización se realiza a través de la propiedad
DataSource, pero cuando no se dispone de ella, se puede utilizar este objeto para realizar dicho enlace.
El objeto más utilizado en la visualización 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
continuación los controles del formulario al componente BindingSource.
Todas la demás interacción con los datos, incluido el desplazamiento, la ordenación, el filtrado y la
actualización, se lleva a cabo con llamadas al componente BindingSource.
El enlace se lleva a cabo a través de la propiedad DataBindings.
Veamos su utilización.
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"
Y además 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 parámetros 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 añadir un nuevo registro.
EnlaceTabla.AddNew()
Una vez que se cumplimentan los datos, si quiere grabarse ha de ejecutarse el método
EnlaceTabla.EndEdit.
Este objeto además permite realizar tareas de navegación, con los métodos que observamos en el
ejemplo.
EnlaceTabla.MoveFirst()
EnlaceTabla.MovePrevious()
EnlaceTabla.MoveNext()
EnlaceTabla.MoveLast()
Y el proceso de actualización 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
2
La actualización debe de arrancar, puede, del evento clic de un button, en el que se ejecuta:
EnlaceTabla.EndEdit()
Actualizar()
La primera línea finaliza la edición del registro que se añadió nuevo, o que se estaba editando.
La segunda llama al procedimiento de actualización.
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 desharán.
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
1.3 CommandBuilder.
Es un objeto que genera de forma automática el código SQL necesario para proceder a la actualización
de una tabla de la base de datos.
No es posible utilizarlo para las tablas que se generen de forma provisional, pues estás tablas suelen
estar compuestas por datos de varias tablas, o para tablas en las que los datos a añadir son una colección de
varios registros.
La utilización 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 gestión 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 más es suficiente para la visualización y la edición de los datos de la tabla.
La utilización del CommandBuilder es como sigue:
Dim ComandoActualizar As OleDb.OleDbCommandBuilder
A continuación su asignación, no debe moverse del sitio pues sino no dispone de la información
necesaria para generar el código 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 visión algo más 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
' 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 ningún cambio en su
utilización, la definición 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
1.4 Command.
Nos permite realizar diversos tipos de operaciones con la base de datos.
Almacena básicamente el código SQL para interactuar con la base de datos, pero dispone de varias
funcionalidades.
En el ejemplo que sigue se usa en la generación de un objeto DataReader para cargar un ListBox con
una consulta incrustada.
Su definición es
Dim Comando As New System.Data.OleDb.OleDbCommand
Después primero le asignamos el código SQL
' Contenido del comando
Comando.CommandText = CadenaSQL
Después le indicamos de que tipo es el código 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.
' Conexión a utilizar, configurada previamente.
Comando.Connection = Conexion
Pasada la fase de definición, se ejecuta el código SQL, asignando el resultado de su ejecución a un
objeto DataReader.
' Ejecución de SQL
Reader = Comando.ExecuteReader
En este caso se ha usado el método ExecuteReader, pero disponemos de otra faceta, para cuando no
hay que devolver datos, ExecuteNonQuery, para las instrucciones Update, Delete por ejemplo.
4
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
' Conexión a utilizar, configurada previamente.
Comando.Connection = Conexion
' Ejecución 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
' Conexión a utilizar, configurada previamente.
Comando.Connection = Conexion
Hay que pensar que el resto es el mismo, solo se ha cambiado la fuente del código SQL, que ahora está
almacenado en la base de datos, y cuando la abra lo capturará.
5
La consulta puede ser que incorpore parámetros, como es el caso del ejemplo que se actualizan datos
en la tabla, en ese caso hay que añadir el valor de los parámetros.
' Añadir parámetros 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 parámetros es el que sigue.
"@Cod",
Es el nombre del parámetro en la consulta almacenada.
OleDb.OleDbType.Char, 2)
Es el tipo de dato que se envía, 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 código 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 definición es la misma y la parametrización también.
Dim Comando As New System.Data.OleDb.OleDbCommand
' código SQL a utilizar
Comando.CommandText = CadenaSQL
' Tipo de comanndo a ejecutar
Comando.CommandType = CommandType.Text
' Conexión a utilizar, configurada previamente.
Comando.Connection = Conexion
El cambio viene a la hora de la ejecución que como no devuelve datos, se usa otro método.
Cuantos = Comando.ExecuteNonQuery
Cuantos es una variable entera que recibe cuantos registros han sido afectados por la ejecución 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)
6
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 & "') "
' código SQL a utilizar
Comando.CommandText = CadenaSQL
' Tipo de comando a ejecutar
Comando.CommandType = CommandType.Text
' Conexión 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
1.5 DataView.
Este objeto permite obtener datos de una tabla a partir de unos criterios definidos.
Tiene la característica 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 actualización de los datos en la base de
datos.
También 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 información.
' Asignación de la tabla
ObjDataView.Table = Tabla
Si deseáramos modificar el contenido de la vista, cambiaríamos a true estos valores.
' No se permite edición.
ObjDataView.AllowDelete = False
ObjDataView.AllowEdit = False
ObjDataView.AllowNew = False
7
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 ordenación.
' campo a usar para la ordenación
ObjDataView.Sort = "RazonSocial"
Después 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 código 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 parámetros
With ObjDataView
' Asignación de la tabla
.Table = Tabla
' No se permite edición.
.AllowDelete = False
.AllowEdit = False
.AllowNew = False
' campo a usar en el filtro
.RowFilter = "Tipo = '" & Tipo & "'"
.RowStateFilter = DataViewRowState.CurrentRows
' campo a usar para la ordenación
.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
8
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 utilización 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 relación 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 añadir las relaciones necesarias para el control del DataSet.
Cuando se añade una relación, 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 gestión 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 ningún código en concreto
para la gestión de una relación.
Los pasos son :
Generar el código SQL,
Asignar los parámetros del objeto OleDbCommand,
Ejecutar el código SQL
Controlar los errores
9
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
' Conexión 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 inserción")
End Try
Conexion.Close()
' Liberar recursos
Comando.Dispose()
Comando = Nothing
End Sub
Podemos ver la ventana con las propiedades de una relación entre dos tablas, conviene hacer hincapié
en el apartado de no activar la opción de eliminar en cascada, de esa forma podemos evitar algún que otro
disgusto.
Con esos pasos es suficiente para la gestión de la relación.
En un DataSet el uso de relaciones mejora la visualización de los datos, con el DataGrid, por ejemplo, ya
que se realiza prácticamente una navegación entre los datos origen y los dependientes.
Solo es asignar el DataSet al DataGrid.
10
Todo lo referente al DataRelatión lo podemos encontrar en.
http://msdn2.microsoft.com/es-es/library/system.data.datarelation(VS.80).aspx
1.7 Restriction.
Representa la restricción de una acción impuesta a un conjunto de columnas en una relación 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 relación de las tablas.
' Establecer los parámetros, grupos alumnos
ColPrincipal = ObjDataSet.Tables("Grupos").Columns("CodGrupo")
ColSecundaria = ObjDataSet.Tables("Alumnos").Columns("Grupo")
Crear la restricción.
Restriccion = New ForeignKeyConstraint("RestGrupoAlumno", _
ColPrincipal, _
ColSecundaria)
Definir las condiciones en borrado, actualización.
' Establecer condiciones de la restricción
Restriccion.DeleteRule = Rule.Cascade
Restriccion.UpdateRule = Rule.Cascade
Restriccion.AcceptRejectRule = AcceptRejectRule.Cascade
Añadir la restricción a las tablas.
' Añadir la restricción
ObjDataSet.Tables("Alumnos").Constraints.Add(Restriccion)
Una vez creada la restricción, hay que marcar su utilización.
' Establecer a True la propiedad EnforceConstraints,
' forzar las restricciones.
ObjDataSet.EnforceConstraints = True
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 parámetros, grupos alumnos
ColPrincipal = ObjDataSet.Tables("Grupos").Columns("CodGrupo")
ColSecundaria = ObjDataSet.Tables("Alumnos").Columns("Grupo")
Restriccion = New ForeignKeyConstraint("RestGrupoAlumno", _
ColPrincipal, _
ColSecundaria)
' Establecer condiciones de la restricción
Restriccion.DeleteRule = Rule.Cascade
Restriccion.UpdateRule = Rule.Cascade
Restriccion.AcceptRejectRule = AcceptRejectRule.Cascade
' Añadir la restricción
ObjDataSet.Tables("Alumnos").Constraints.Add(Restriccion)
' Añadir la restricción
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 parámetros, 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 restricción
Restriccion.DeleteRule = Rule.Cascade
Restriccion.UpdateRule = Rule.Cascade
Restriccion.AcceptRejectRule = AcceptRejectRule.Cascade
' Añadir la restricción
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
1.8 Definición de claves.
El uso de las tablas conlleva la gestión de los registros y el control de las duplicidades y la localización
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 método.
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 ejecución de la línea con el método FillSchema.
Su utilización posteriormente puede ser como sigue en el ejemplo, en el cual se utiliza para realizar la
actualización del campo de entradas acumuladas.
La explicación 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 método Find.
Dim Registro As System.Data.DataRow
Registro = ObjDataSet.Tables("Titulos").Rows.Find(Clave)
13
Si se encuentra se actualiza el dato, para ello se utiliza el valor del índice del registro leído.
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 código 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 actualización stocks")
End Try
End Sub
La definición de una clave principal se realiza así, restricción 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 añade 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
1.9 Transacción.
Es el objeto que nos va a permitir realizar los procesos de actualización con la seguridad de poder
mantener la integridad de la base de datos.
La definición y utilización del mismo es como sigue.
' Definición del objeto
Dim Transaccion As System.Data.OleDb.OleDbTransaction
' Inicio de la transacción
Transaccion = Conexion.BeginTransaction(IsolationLevel.Chaos)
' Final correcto de la transacción
Transaccion.Commit()
' Final por error de la transacción, abortar.
Transaccion.Rollback()
Solo queda integrar cada instrucción en el punto adecuado del programa.
Cuando el proceso de transacción está en marcha, se ha de tener en cuenta no lanzarlo para un proceso
muy amplio, si no en unidades lógicas de actualización, no para un programa completo vamos.
Como el proceso de actualización se ejecuta para varias tablas, cada una de esas tablas se actualiza
con su DataAdapter, y en cada uno de esos procesos de actualización es necesario la presencia de un objeto
OleDbCommand, el objeto OleDbCommand necesita que se le pase el objeto Transacción que estemos
utilizando en ese momento, por lo tanto el uso del objeto OleDbCommand quedaría como sigue:
' Cadena SQL
Comando.CommandText = CadenaSQL
' Tipo de comando a ejecutar
Comando.CommandType = CommandType.Text
' Conexión a utilizar, configurada previamente.
Comando.Connection = Conexión
' Asignación del objeto transacción en curso.
Comando.Transaction = Transaccion
Por lo tanto en el procedimiento de actualización de cada una de las tablas del programa hay que hacer
el cambio o que esté presente
' Asignación del objeto transacción en curso.
Comando.Transaction = Transaccion
para su correcto funcionamiento.
El ejemplo que sigue empieza comprobando si hay cambios en el DataSet.
15
If ObjDataSet.HasChanges Then
Después si es así, se entra en el proceso de actualizar.
Se inicia la transacción.
Conexion.Open()
' Inicio de la transacción
Transaccion = Conexion.BeginTransaction(IsolationLevel.Chaos)
Se asigna cada OleDbCommand con el objeto conexión y con la transacción.
Comando.Connection = Conexion
Comando.Transaction = Transaccion
Se capturan los cambios en el DataSet copiándolos a un nuevo DataSet, en el ejemplo todos,
modificados, borrados e insertados.
ObjDataSetCamb = ObjDataSet.GetChanges(DataRowState.Modified _
Or DataRowState.Added _
Or DataRowState.Deleted)
Después se repite tabla a tabla el proceso de actualización.
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 transacción.
If Not Fallo Then
' Final correcto de la transacción
Transaccion.Commit()
MsgBox("Base actualizada.", MsgBoxStyle.Information, _
"Actualizando dataset")
Else
' Final por error de la transacción
Transaccion.Rollback()
MsgBox("Actualización 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 transacción
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 transacción
Transaccion.Commit()
MsgBox("Base actualizada.", MsgBoxStyle.Information,”Actualizar")
Else
' Final por error de la transacción
Transaccion.Rollback()
MsgBox("Actualización 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
Descargar