none
Comparar esquemas de dos bases de datos RRS feed

  • Pregunta

  • Buenas!

     

    Tengo un pequeño problema. Tengo que comparar la estructura de dos bases de datos Access usando Vb.net. Usando el documentador de Access pude obtener un reporte de la bd, pero no se como puedo compararlo con el otro, o si hay alguna otra forma de hacerlo.

     

    No puedo usar software de terceros, lo tengo que desarrollar personalmente.

     

    Conocen alguna forma?

     

    Un saludo y muchas gracias.

    • Cambiado Enrique M. Montejo martes, 2 de agosto de 2011 11:25 acceso a datos (De:Lenguaje VB.NET)
    lunes, 1 de agosto de 2011 17:08

Respuestas

  • Hola,

    Solo te queda armar una clase que contenga un par de propiedades por campo para establecer las características del mismo (nombre, tipo de dato, estado de actualización) para poder armar la sincronización. Algo así como:

    Class Tabla
      Property Nombre as String
      Property Estado as String ' En realidad un Enum de acuerdo a tus necesidades
      Public Sub New()
      End Sub
      Public Sub New(nombre as String) 
        Me.Nombre = nombre
      End Sub
    End Class
    
    Class Tablas
       Inherits List(Of Tabla)
    End Class
    
    
    'En tu código
    Tablas = New Tablas
    Tablas.Add(New Tabla(R("Table_name")))
    
    

    Esta instrucción ReDim Preserve tablas(i + 1) podes cambiarla por

    Dim Tablas as New List(Of String)

    y Tablas.add( r("TABLE_NAME").ToString )

    Trata de no trabajar con Objects, definiendo las variables del tipo que sean.

    Dim o As Object = Nothing.

    Saludos!

    • Propuesto como respuesta MarianoIT miércoles, 3 de agosto de 2011 11:02
    • Marcado como respuesta criska_ miércoles, 3 de agosto de 2011 12:37
    miércoles, 3 de agosto de 2011 11:02

Todas las respuestas

  • Hola,

    Tendrías que tomar cada campo de la tabla A y compararlo con la tabla B para marcar que existe y que no. Luego tomas la tabla B y la comparas con la tabla A para luego marcar lo que existe y que no. Al final comparas las marcas de ambas tablas para verificar que tenes que modificar (agregar, actualizar o borrar), siempre teniendo una de las tablas como principal.

    Saludos.

     

    martes, 2 de agosto de 2011 11:31
  • Gracias Mariano por tu respuesta.

     

    Estoy usando el siguiente código, pero tengo un problema, y es que no me devuelve correctamente los nombres de las tablas:

     

    Public Class Form1
    
     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
     Dim conexion As OleDb.OleDbConnection
     Dim strConexion As String
     Dim tablas(0) As String
    
     '-- Conexion con la base de datos --
     strConexion = "Provider=Microsoft.jet.OLEDB.4.0;Data Source=C:\base.mdb;Jet OLEDB:Database Password=pass;"
     conexion = New OleDb.OleDbConnection(strConexion)
     conexion.Open()
    
     '-- Almacena en un vector los nombres de todas las tablas --
     Dim tabla As DataTable = conexion.GetSchema("Tables")
     Dim i As Integer = 0
     For Each r As DataRow In tabla.Rows
     tablas(i) = r("Table_name").ToString
     ReDim Preserve tablas(i + 1)
     i += 1
     Next
     MessageBox.Show(tablas(1))
     conexion.Close()
    
     End Sub
    End Class
    

     

    Pero no le encuentro el error :\ Alguna sugerencia?

     

    Edito:

    No era un error al final. Lo que pasaba es que además de las tablas, también me devolvía todas las consultas.

    Acá está el código corregido:

     

    Public Class Form1
    
     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
      Dim conexion As OleDb.OleDbConnection
      Dim strConexion As String
      Dim tablas(0) As String
    
      '-- Conexion con la base de datos --
      strConexion = "Provider=Microsoft.jet.OLEDB.4.0;Data Source=C:\base.mdb;Jet OLEDB:Database Password=pass;"
    conexion = New OleDb.OleDbConnection(strConexion) conexion.Open() '-- Almacena en un vector los nombres de todas las tablas -- Dim tabla As DataTable = conexion.GetSchema("TABLES") Dim i As Integer = 0 For Each r As DataRow In tabla.Rows Dim o As Object = Nothing o = r.Item("TABLE_TYPE") If (o.ToString.ToUpper = "TABLE") OrElse (o.ToString.ToUpper = "BASE_TABLE") Then ' Si llega hasta aca el objeto es una tabla tablas(i) = r("TABLE_NAME").ToString ReDim Preserve tablas(i + 1) i += 1 End If Next MessageBox.Show(tablas(1)) conexion.Close() End Sub End Class

     


    Muchas gracias por la ayuda.

     

    Un saludo.

     


    martes, 2 de agosto de 2011 12:43
  • Hola,

    Solo te queda armar una clase que contenga un par de propiedades por campo para establecer las características del mismo (nombre, tipo de dato, estado de actualización) para poder armar la sincronización. Algo así como:

    Class Tabla
      Property Nombre as String
      Property Estado as String ' En realidad un Enum de acuerdo a tus necesidades
      Public Sub New()
      End Sub
      Public Sub New(nombre as String) 
        Me.Nombre = nombre
      End Sub
    End Class
    
    Class Tablas
       Inherits List(Of Tabla)
    End Class
    
    
    'En tu código
    Tablas = New Tablas
    Tablas.Add(New Tabla(R("Table_name")))
    
    

    Esta instrucción ReDim Preserve tablas(i + 1) podes cambiarla por

    Dim Tablas as New List(Of String)

    y Tablas.add( r("TABLE_NAME").ToString )

    Trata de no trabajar con Objects, definiendo las variables del tipo que sean.

    Dim o As Object = Nothing.

    Saludos!

    • Propuesto como respuesta MarianoIT miércoles, 3 de agosto de 2011 11:02
    • Marcado como respuesta criska_ miércoles, 3 de agosto de 2011 12:37
    miércoles, 3 de agosto de 2011 11:02
  • Gracias por la respuesta Mariano!

     

    Una última consulta. No entiendo como puedo hacer para obtener el nombre de los campos de las tablas que voy almacenando, como lo podría hacer? 

     

    Un saludo y perdón por las preguntas.

    miércoles, 3 de agosto de 2011 11:54
  • Aca va el código de ejemplo para recuperar los campos

     For Each itm As DataRow In tabla.Rows
          Dim cmd = conexion.CreateCommand()
          cmd.Connection = conexion
          cmd.CommandText = "SELECT * FROM Employees where 1=0" ' Forzar a que traiga solo el esquema
          Dim myReader = cmd.ExecuteReader()
          Dim schemaTable = myReader.GetSchemaTable()
    
          ' schemaTable.Rows
    Next
    

     Saludos!

    miércoles, 3 de agosto de 2011 12:10
  • Al tratar de ejecutar esta línea:

      cmd.CommandText = "SELECT * FROM " & tablas(i) & " WHERE 1=0"
      Dim lector = cmd.ExecuteReader
    

    Me dice:

    Error de sintaxis en la cláusula FROM

    Tengo que usar una estructura similar ya que debo devolver todos los campos de todas las tablas.

     

    Edito:

    Ya encontré el problema. Me faltaba poner corchetes en la consulta.

    cmd.CommandText = "SELECT * FROM [" & tablas(i) & "] WHERE 1=0"
    

     

    Muchas gracias Mariano por tu ayuda.

     

    Un saludo.



    • Editado criska_ miércoles, 3 de agosto de 2011 12:36
    miércoles, 3 de agosto de 2011 12:22
  • Fijate de realizar esto... nunca concatenes con & sino con String.Format()

    cmd.CommandText = String.Format("Select * From [{0}] Where 1=0", Tablas(i))

    Debug.Print (Cmd.CommandText)

    Verifica si es con todas las tablas o con alguna en especial.

    Crucemos los dedos!

    • Propuesto como respuesta MarianoIT miércoles, 3 de agosto de 2011 12:33
    miércoles, 3 de agosto de 2011 12:32