Ho un progetto da completare per la sincronizzazione di database. ho un problema nella lettura del formato dei campi da un tipo di database e la creazione dei campi nella tabella del database di destinazione che è di un formato diverso. i formati database principalmente coinvolti sono MySql, Firebird, Ms Access, Ms SqlServer
ho provato la strada di una tabella con i formati dei campi dei diversi database ma credo non sia la strada giusta.
Public Function LeggiStrutturaTabella(intMasterDbId As Integer,
strMasterDNS As String,
strMasterPercorso As String,
strMasterPorta As String,
strMasterDLL As String,
strMasterSetCaratteri As String,
strMasterNome As String,
strMasterNomeUtente As String,
strMasterPassword As String,
strMasterTabellaNome As String,
intMasterTipologiaDatabaseId As Integer,
intDestDbId As Integer,
strDestDNS As String,
strDestPercorso As String,
strDestPorta As String,
strDestDLL As String,
strDestSetCaratteri As String,
strDestNome As String,
strDestNomeUtente As String,
strDestPassword As String,
strDestTabellaNome As String,
intDestTipologiaDatabaseId As Integer) As DataTable
Dim strNomeRoutine As String = System.Reflection.MethodBase.GetCurrentMethod().Name
Dim ConnDbMaster As IDbConnection = DataBaseCaricato.ConnettiDbMaster(intMasterTipologiaDatabaseId,
strMasterDNS,
strMasterPercorso,
strMasterPorta,
strMasterDLL,
strMasterNome,
strMasterNomeUtente,
strMasterPassword,
strMasterSetCaratteri)
Dim ConnDbDestinazione As IDbConnection = DataBaseCaricato.ConnettiDbDestinazione(intDestTipologiaDatabaseId,
strDestDNS,
strDestPercorso,
strDestPorta,
strDestDLL,
strDestNome,
strDestNomeUtente,
strDestPassword,
strDestSetCaratteri)
' Apriamo la connessione ConnDbMaster
If ConnDbMaster.State = ConnectionState.Closed Then
ConnDbMaster.Open()
End If
' Apriamo la connessione ConnDbDestinazione
If ConnDbDestinazione.State = ConnectionState.Closed Then
ConnDbDestinazione.Open()
End If
Dim dtStrutturaMaster As New DataTable()
Dim dtStrutturaDest As New DataTable()
Dim tabellaEsistente As Boolean = False
Dim queryCheckTable As String = ""
Select Case intDestTipologiaDatabaseId
Case 1 ' MS Access
queryCheckTable = $"SELECT COUNT(*) FROM MSysObjects WHERE Type=1 AND Name='{strDestTabellaNome}'"
Case 2 ' MySQL
queryCheckTable = $"SELECT 1 FROM information_schema.tables WHERE table_schema = '{strDestNome}' AND table_name = '{strDestTabellaNome}'"
Case 4 ' Firebird
queryCheckTable = $"SELECT COUNT(*) FROM RDB$RELATIONS WHERE RDB$RELATION_NAME = '{strDestTabellaNome}'"
Case Else
Throw New ArgumentException("Tipologia di database di destinazione non supportata per la verifica della tabella esistente")
End Select
Dim commandCheckTable As IDbCommand = ConnDbDestinazione.CreateCommand()
commandCheckTable.CommandText = queryCheckTable
Dim result As Integer = CInt(commandCheckTable.ExecuteScalar())
If result > 0 Then
tabellaEsistente = True
End If
If Not tabellaEsistente Then
' La tabella di destinazione non esiste, quindi crea la tabella
Dim queryCreateTable As String = ""
' Carica la struttura della tabella del database master
If ConnDbMaster IsNot Nothing AndAlso ConnDbMaster.State = ConnectionState.Open Then
Dim queryMaster As String
If intDbMasterTipologiaId = 1 Then 'Ms Access
queryMaster = $"SELECT * FROM [{strMasterTabellaNome}]"
Else
queryMaster = $"SHOW COLUMNS FROM {strMasterTabellaNome}" ' Correggi il nome della variabile tabellaNome
End If
Dim CommandMaster As IDbCommand = ConnDbMaster.CreateCommand()
CommandMaster.CommandText = queryMaster
Dim DataAdapterMaster As IDbDataAdapter
If TypeOf ConnDbMaster Is MySqlConnection Then
DataAdapterMaster = New MySqlDataAdapter(DirectCast(CommandMaster, MySqlCommand))
ElseIf TypeOf ConnDbMaster Is FbConnection Then
DataAdapterMaster = New FbDataAdapter(DirectCast(CommandMaster, FbCommand))
ElseIf TypeOf ConnDbMaster Is OleDbConnection Then
DataAdapterMaster = New OleDbDataAdapter(DirectCast(CommandMaster, OleDbCommand))
Else
Throw New ArgumentException("Tipologia di database non supportata")
End If
Dim readerMaster As IDataReader = CommandMaster.ExecuteReader()
' Carica i dati direttamente nel DataTable
dtStrutturaMaster.Load(readerMaster)
Else
DataBaseCaricato.ScriviLogErrore(DateTime.Now, strNomeRoutine, "0", "Problemi di connessione: ConnDbMaster")
End If
' Aggiunta delle colonne in base ai dati estratti dalla tabella del database master
For Each column As DataColumn In dtStrutturaMaster.Columns
Dim nomeColonna As String = column.ColumnName ' Sostituisci 'NomeColonna' con il nome effettivo della colonna
Dim tipoDato As String = dtStrutturaMaster.Rows(0)(column.ColumnName).GetType().Name ' Ottieni il tipo di dati della colonna nella prima riga del DataTable
DataBaseCaricato.ScriviLogErrore(DateTime.Now, strNomeRoutine, "0", nomeColonna & " " & tipoDato)
' Trova l'ID del formato campo utilizzando la sigla campo e la tipologia del database
Dim queryFormatoCampoId As String = $"SELECT FormatoCampoId FROM vFormatoCampiDataBase WHERE SiglaCampo = '{tipoDato}' AND TipologiaDataBaseId = {intMasterTipologiaDatabaseId};"
' Esegui la query per ottenere l'ID del formato campo utilizzando la connessione al database principale
Dim formatoCampoId As Integer = 0
Using command As New MySqlCommand(queryFormatoCampoId, DataBaseCaricato.ConnettiDbPrincipale()) ' Sostituisci MySqlCommand con il tipo di comando e ConnettiDbPrincipale() con la funzione di connessione al database principale
Dim resultFormatoCampoId As Object = command.ExecuteScalar()
If resultFormatoCampoId IsNot Nothing AndAlso Not DBNull.Value.Equals(resultFormatoCampoId) Then
formatoCampoId = Convert.ToInt32(resultFormatoCampoId)
End If
End Using
' Utilizza l'ID del formato campo per recuperare la sigla del campo dalla vista vFormatoCampiDataBase
Dim querySiglaCampo As String = $"SELECT SiglaCampo FROM vFormatoCampiDataBase WHERE FormatoCampoId = {formatoCampoId} AND TipologiaDataBaseId = {intDestTipologiaDatabaseId};"
'DataBaseCaricato.ScriviLogErrore(DateTime.Now, strNomeRoutine, "0", querySiglaCampo)
' Esegui la query per ottenere la sigla del campo utilizzando la connessione al database principalex
Dim strSiglaCampo As String = String.Empty
Using command As New MySqlCommand(querySiglaCampo, DataBaseCaricato.ConnettiDbPrincipale()) ' Sostituisci MySqlCommand con il tipo di comando e ConnettiDbPrincipale() con la funzione di connessione al database principale
strSiglaCampo = command.ExecuteScalar()?.ToString()
End Using
'DataBaseCaricato.ScriviLogErrore(DateTime.Now, strNomeRoutine, "0", nomeColonna & " " & strSiglaCampo)
' Aggiungi la colonna alla query di creazione della tabella con il formato nome recuperato
queryCreateTable &= $"{nomeColonna} {strSiglaCampo}"
If column IsNot dtStrutturaMaster.Columns(dtStrutturaMaster.Columns.Count - 1) Then
queryCreateTable &= ", "
End If
Next
Exit Function
' Aggiungi la parentesi chiusa alla fine della query di creazione della tabella
queryCreateTable = $"CREATE TABLE {strDestTabellaNome} ({queryCreateTable})"
Console.WriteLine(queryCreateTable) ' Stampare la query per il debug
frmPrincipale.txtErrore.Text = queryCreateTable
DataBaseCaricato.ScriviLogErrore(DateTime.Now, strNomeRoutine, "0", queryCreateTable)
Dim commandCreateTable As IDbCommand = ConnDbDestinazione.CreateCommand()
commandCreateTable.CommandText = queryCreateTable
commandCreateTable.ExecuteNonQuery()
End If
'Try
If ConnDbMaster IsNot Nothing Then
Dim queryMaster As String
Dim queryDestinazione As String
If intDbMasterTipologiaId = 1 Then 'Ms Access
queryMaster = $"SELECT * FROM [{strMasterTabellaNome}]"
Else
queryMaster = "SHOW COLUMNS FROM " & strMasterTabellaNome ' Correggi il nome della variabile tabellaNome
End If
Dim CommandMaster As IDbCommand = ConnDbMaster.CreateCommand()
CommandMaster.CommandText = queryMaster
If intDbDestTipologiaId = 1 Then
queryDestinazione = $"SELECT * FROM [{strMasterTabellaNome}]"
Else
queryDestinazione = "SHOW COLUMNS FROM " & strMasterTabellaNome ' Correggi il nome della variabile tabellaNome
End If
Dim CommandDest As IDbCommand = ConnDbDestinazione.CreateCommand() ' Correggi il nome della variabile ConnDbDestinazione
CommandDest.CommandText = queryDestinazione
Dim DataAdapterMaster As IDbDataAdapter
If TypeOf ConnDbMaster Is MySqlConnection Then
DataAdapterMaster = New MySqlDataAdapter(DirectCast(CommandMaster, MySqlCommand))
ElseIf TypeOf ConnDbMaster Is FbConnection Then
DataAdapterMaster = New FbDataAdapter(DirectCast(CommandMaster, FbCommand))
ElseIf TypeOf ConnDbMaster Is OleDbConnection Then
DataAdapterMaster = New OleDbDataAdapter(DirectCast(CommandMaster, OleDbCommand))
Else
Throw New ArgumentException("Tipologia di database non supportata")
End If
If ConnDbMaster.State = ConnectionState.Closed Then
ConnDbMaster.Open()
End If
If ConnDbMaster IsNot Nothing AndAlso ConnDbMaster.State = ConnectionState.Open Then
Dim readerMaster As IDataReader = CommandMaster.ExecuteReader()
' Carica i dati direttamente nel DataTable
dtStrutturaMaster.Load(readerMaster)
Else
DataBaseCaricato.ScriviLogErrore(DateTime.Now, strNomeRoutine, "0", "Problemi di connessione: ConnDbMaster")
End If
Dim DataAdapterDest As IDataAdapter
If TypeOf ConnDbDestinazione Is MySqlConnection Then ' Correggi il nome della variabile ConnDbDestinazione
DataAdapterDest = New MySqlDataAdapter(DirectCast(CommandDest, MySqlCommand))
ElseIf TypeOf ConnDbDestinazione Is FbConnection Then ' Correggi il nome della variabile ConnDbDestinazione
DataAdapterDest = New FbDataAdapter(DirectCast(CommandDest, FbCommand))
ElseIf TypeOf ConnDbDestinazione Is OleDbConnection Then ' Correggi il nome della variabile ConnDbDestinazione
DataAdapterDest = New OleDbDataAdapter(DirectCast(CommandDest, OleDbCommand))
Else
Throw New ArgumentException("Tipologia di database non supportata")
End If
If ConnDbDestinazione.State = ConnectionState.Closed Then
ConnDbDestinazione.Open()
End If
If ConnDbDestinazione IsNot Nothing AndAlso ConnDbDestinazione.State = ConnectionState.Open Then
Dim readerDestinazione As IDataReader = CommandDest.ExecuteReader()
' Carica i dati direttamente nel DataTable
dtStrutturaDest.Load(readerDestinazione)
Else
DataBaseCaricato.ScriviLogErrore(DateTime.Now, strNomeRoutine, "0", "Problemi di connessione: ConnDbDestinazione")
End If
VerificaStrutturaTabelle(dtStrutturaMaster, dtStrutturaDest)
Else
' Gestisci il fallimento della connessione
DataBaseCaricato.ScriviLogErrore(DateTime.Now, strNomeRoutine, "", "Problemi di connessione")
End If
Try
Catch ex As Exception
' Gestisci gli errori
DataBaseCaricato.ScriviLogErrore(DateTime.Now, strNomeRoutine, ex.HResult, ex.Message)
Finally
' Chiudi la connessione solo se è stata aperta
If ConnDbMaster IsNot Nothing AndAlso ConnDbMaster.State = ConnectionState.Open Then
ConnDbMaster.Close()
End If
End Try
Return dtStrutturaMaster ' Restituisci il DataTable della struttura del database master
End Function