Почему моя БД не обновляет объединенные таблицы? - PullRequest
0 голосов
/ 09 мая 2018

Я застрял, пытаясь выяснить, почему моя база данных не получает объединенные данные из кода ниже.

Ниже приведен код (PS: он НЕ чистый, но закомментирован!):

  1. Подключается к выбранной книге XLSX (всегда ищет Sheet1 прямо сейчас).
  2. Загружает Sheet1 в DataSet (DtSet) с именем таблицы "XLSheet".
  3. Я создаю переменную DataTable с именем dt и указываю на приведенную выше таблицу «XLSheet»
  4. Я подключаю к своим приложениям локальную базу данных SQLite.
  5. Я снова выполняю текст команды из базы данных SQLite в DROP TABLE XLImport (таблица, в которую я пытаюсь импортировать).
  6. Я воссоздаю таблицу, используя динамический SQL, чтобы объединить вместе новый оператор CREATE TABLE, потому что каждый XLSheet будет иметь уникальные заголовки столбцов (они приходят из многих, многих источников). Это гарантирует, что мои таблицы XLSheet и XLImport имеют одинаковую схему, и ни одна из них не имеет PK .
  7. Я создаю набор данных из адаптера данных SQLite, который указывает на новую таблицу XLImport.
  8. Я создаю объект DataTable и указываю его на таблицу XLImport.
  9. Я объединяю две таблицы данных, используя dt2.Merge (dt) 10. ??? Как я могу передать это слияние обратно в базу данных SQLite через dataAdapter ??? Вот код

    Private Sub cmdImportFile_Click(sender As Object, e As EventArgs) Handles cmdImportFile.Click
    Dim bHeaders As Boolean = chkHeaders.CheckState
    Dim oFile As System.IO.FileInfo = My.Computer.FileSystem.GetFileInfo(txtFilePath.Text)
    Dim sFile As String = oFile.Name
    Dim sFilePath As String = oFile.DirectoryName
    Dim da As SQLite.SQLiteDataAdapter
    Dim ds As New DataSet
    Dim dt2 As New DataTable
    
    Try
        Dim XLConn As System.Data.OleDb.OleDbConnection
        Dim DtSet As New System.Data.DataSet
        Dim XLDataAdapter As System.Data.OleDb.OleDbDataAdapter
    
    
        'Create connection to selected XLSX workbook, Sheet1
        XLConn = New System.Data.OleDb.OleDbConnection _
        ("provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & oFile.FullName & "; Extended Properties=""Excel 12.0 Xml;HDR=" & bHeaders & "; IMEX=1"";")
        XLDataAdapter = New System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", XLConn)
    
        'Open and fill dataset to table 'XLSheet'
        XLDataAdapter.Fill(DtSet, "XLSheet")
        XLConn.Close()
    
        'Setup DataTable object
        Dim dt As DataTable = DtSet.Tables("XLSheet")
    
        'Connect to SQLite
        Dim sAppPath As String = Application.StartupPath
    
        'When debugging, this changes the AppPath value to remove the \bin\Debug portion of the AppPath
        If Debugger.IsAttached Then sAppPath = sAppPath.Replace("\bin\Debug", "")
        Dim connString As String = "Data Source = " & sAppPath & "\biodata.db;version=3;"
        Dim sDBPath As String = sAppPath & "\biodata.db"
    
        'Connect to DB
        conn = New SQLiteConnection(connString)
        conn.Open()
    
        'Drop Existing "XLImport" table
        Dim cmd As SQLiteCommand
        Dim sDROPSQL As String = "DROP TABLE IF EXISTS XLImport;"
        cmd = conn.CreateCommand()
        cmd.CommandText = sDROPSQL
        cmd.ExecuteReader()
        cmd.Dispose()
    
        'Build dynamic SQL string for CREATE TABLE based on imported XLS file (they have dynamic headers!)
        Dim iMax As Integer = dt.Columns.Count
        Dim i As Integer = 1
        Dim sSQL As String = "CREATE TABLE XLImport("
    
        For Each c As DataColumn In dt.Columns
            Debug.Print(c.DataType.ToString)
            sSQL = sSQL & "[" & c.ColumnName & "] "     & ConvertXLDataTypeToSQLite(c.DataType.ToString)
            If i < iMax Then sSQL = sSQL & ","
            i = i + 1
        Next
    
        sSQL = sSQL & ");"
    
    
        'Create Table "XLImports" from Dynamic SQL Statement
        cmd = conn.CreateCommand
        cmd.CommandText = sSQL
        cmd.ExecuteReader()
        cmd.Dispose()
        conn.Close()
    
        'Open SQLite DB 
        cmd = conn.CreateCommand
        cmd.CommandText = "SELECT * FROM XLImport"
        conn.Open()
        da = New SQLiteDataAdapter(cmd.CommandText, conn)
    
        'Fill Dataset table "XLImport" from db, which is always EMPTY.
        da.Fill(ds, "XLImport")
    
        'Create DataTable object for 'XLImport'
        dt2 = ds.Tables("XLImport")
    
        'Merge the two dataTables - NO PRIMARY KEY ON EITHER DataTable
        dt2.Merge(dt)
    
        da.Update(ds.Tables("XLImport"))
    
    
    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
    
    End Sub
    
    Private Function ConvertXLDataTypeToSQLite(sDataType As String) As String
    Dim sNewDataType As String
    
    Select Case sDataType
    
        Case "System.Int64"
            sNewDataType = "NUMBER"
        Case "System.Int16"
            sNewDataType = "NUMBER"
        Case "System.Byte"
            sNewDataType = "NUMBER"
        Case "System.Byte[]"
            sNewDataType = "NUMBER"
        Case "System.Int32"
            sNewDataType = "NUMBER"
        Case "System.UInt16"
            sNewDataType = "NUMBER"
        Case "System.Double"
            sNewDataType = "DOUBLE"
        Case "System.String"
            sNewDataType = "VARCHAR(255)"
        Case "System.DateTime"
            sNewDataType = "DATETIME"
        Case "System.GUID"
            sNewDataType = "INTEGER"
        Case "System.Decimal"
            sNewDataType = "DECIMAL"
        Case "System.Boolean"
            sNewDataType = "NUMBER"
        Case "System.Single"
            sNewDataType = "NUMBER"
        Case Else
            sNewDataType = "ERROR"
    End Select
    
    Return sNewDataType
    End Function
    

    Конечный класс

Любая помощь будет принята с благодарностью (и на всякий случай, заранее спасибо Мэри;))

1 Ответ

0 голосов
/ 10 мая 2018

Решено!

Проблема заключалась в том, что у каждого DataRow был RowState без изменений (как указывает Мэри в комментариях). Решением было добавить For Each между командами Merge и Update.

dt2.Merge(dt)

        For Each r As DataRow In dt2.Rows
            r.SetAdded()
        Next

da.Update(dt2)

+ 1 к Мэри за это!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...