将数据从数据库表移动到另一个表

move data from database table to another table

提问人:Vector 提问时间:11/12/2023 最后编辑:Vector 更新时间:11/14/2023 访问量:69

问:

我使用SQLite DB创建了一个 VB.Net 应用程序,并添加了一些数据 我可以执行所有 CRUD 功能 现在我回到应用程序并添加了一个带有此代码的新表 TxArchiveData 注意我在新表中省略了这部分代码

NOT NULL PRIMARY KEY AUTOINCREMENT

在下面创建 TxArchiveData TABLE 的代码

        Private Sub btnNewTable_Click(sender As Object, e As EventArgs) Handles btnNewTable.Click
        'create table TxArchiveDataTable String for cmd
        Dim create_table As String = String.Empty
        create_table = "CREATE TABLE IF NOT EXISTS TxArchiveData(
                        TID INTEGER,
                        txSortDate TEXT,
                        txAmount TEXT,
                        txYear INTEGER,
                        txSearchMonth INTEGER)"

        Dim dbTable As String = "TxArchiveData"

        If Not My.Computer.FileSystem.FileExists(dbTable) Then
            Try
                Using conn As New SQLiteConnection(connStr)
                    conn.Open()
                    Using cmd As New SQLiteCommand(create_table, conn)
                        cmd.ExecuteNonQuery()
                    End Using
                End Using
                tbMessage.Text = "TABLE Created Select BACK"
            Catch ex As Exception
                tbMessage.Text = "TxArchiveData Table FAILED"
            End Try
        End If

下面是创建 TxData TABLE NOTE 共享命名的代码

      Public Sub makeTxData()

        'create table TxDataTable String for cmd
        Dim create_table As String = String.Empty
        create_table = "CREATE TABLE IF NOT EXISTS TxData(
                        TID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
                        txSortDate TEXT,
                        txAmount TEXT,
                        txYear INTEGER,
                        txSearchMonth INTEGER)"

        Dim dbTable As String = "TxDataTable"

        If Not My.Computer.FileSystem.FileExists(dbTable) Then
            Try
                Using conn As New SQLiteConnection(connStr)
                    conn.Open()
                    Using cmd As New SQLiteCommand(create_table, conn)
                        cmd.ExecuteNonQuery()
                    End Using
                End Using
                tbMessage.Text = "DB Created Select BACK"
            Catch ex As Exception
                tbMessage.Text = "TxData Table FAILED"
            End Try
        End If

    End Sub

在另一个我没有打开SQLite DB的窗体上,我放置了这段代码

     Private Sub btnMoveData_Click(sender As Object, e As EventArgs) Handles btnMoveData.Click
        Dim TxData As DataTable = New DataTable()
        Dim TxArchiveData As DataTable = New DataTable()
        For Each row As DataRow In TxData.Rows
            TxArchiveData.ImportRow(row)
        Next
    End Sub

问题是我是否需要连接到数据库才能使 IMPORT ROW 工作,如果是这样,如何工作?

我也在尝试只移动与 txYear 列匹配的数据,将此功能添加到答案中将非常有帮助**

我走到这一步仍然迷失了代码


       Private Sub btnDelete_Click(sender As Object, e As EventArgs) Handles btnDelete.Click
        Dim TxData As New DataTable
        Dim TxArchiveData As New DataTable

        Using conn As New SQLiteConnection($"Data Source = '{gv_dbName}';Version=3;")
            conn.Open()
            Using cmd As New SQLiteCommand("", conn)

                cmd.CommandText = "SELECT * FROM TxData"
                For Each dr As DataRow In TxData.Rows
                    TxArchiveData.ImportRow(dr)
                Next

            End Using
        End Using

    End Sub

vb.net sqlite

评论

3赞 Steve 11/12/2023
是的,您需要连接到数据库。运行命令将源表填充到 DataTable 对象中,然后可以使用内存中的其他 DataTable 对象移动数据。考虑搜索有关 ADO.NET 框架如何工作的某种教程。
0赞 Vector 11/12/2023
@Steve 在搜索和阅读爸爸填充(dtd)后添加了修改后的代码 不确定我错过了什么 如果你有时间看一看
0赞 Steve 11/12/2023
是的,没错。现在,您有一个名为 dtb 的局部变量,该变量已填充了来自名为 txData 的数据库表的数据 当然,如果数据库表为空,则 DataTable 类型的局部变量也是如此。
0赞 jmcilhinney 11/12/2023
没有人应该阅读评论来理解这个问题。如果有与问题相关的新代码,请将其添加到问题中并解释该相关性。
0赞 Vector 11/13/2023
@jmcilhinney好的,我删除了冒犯性的评论,所以现在让我们努力解决我正在阅读的关于克隆和复制表以及 IMPORTROW flylib.com/books/en/1.105.1/ 的问题......

答:

2赞 jmcilhinney 11/13/2023 #1

这里有许多问题需要解决。

首先:

我是否需要连接到数据库才能使 IMPORT ROW 工作,如果需要,如何工作?

不,你当然没有。 将 A 从一个复制到另一个。就是这样,仅此而已。和数据库之间没有直接连接。如何填充源以及如何处理目标的内容与 的使用 无关。如果源数据来自数据库,那么显然您需要连接到该数据库才能检索该数据,但这无关紧要。ImportRowDataRowDataTableDataTablesDataTableDataTableImportRow

其次,没有必要或没有必要使用 .你只需要一个.您还需要一个数据适配器。的数据适配器在调用时执行,调用时可以执行。没有什么可说的,他们需要引用同一个数据库表,甚至同一个数据库。您可以从一个表中获取数据,也可以在另一个表中获取数据,例如ImportRowDataTableSelectCommandFillInsertCommandUpdateSELECTINSERT

Using connection As New SqlConnection("connection string here"),
      insertCommand As New SqlCommand("INSERT INTO Table2 (Col1, Col2) VALUES (@Col1, @Col2)", connection),
      adapter As New SqlDataAdapter("SELECT * FROM Table1", connection) With {.AcceptChangesDuringFill = False,
                                                                              .InsertCommand = insertCommand}
    With insertCommand.Parameters
        .Add("@Col1", SqlDbType.NVarChar, 50, "Col1")
        .Add("@Col1", SqlDbType.Int, 0, "Col2")
    End With

    connection.Open()

    Dim table As New DataTable

    adapter.Fill(table)
    adapter.Update(table)
End Using

需要注意的重要一点是属性的设置。当您将 a 添加到 时,默认情况下是 。调用 时,它会将检索到的行相加,然后调用 ,以便将所有 都设置为 。通过设置为 ,可以确保所有行都保持 ,随时可以插入。AcceptChangesDuringFillDataRowDataTableRowStateAddedFillAcceptChangesRowStatesUnchangedAcceptChangesDuringFillFalseAdded

话虽如此,您甚至不需要在应用中检索任何数据来填充新的数据库表。您可以使用 SELECT INTO 创建新表,从现有表中选择记录并将其插入到新表中。如果目标表已经存在,则可以插入其中并使用查询作为源而不是子句,例如VALUES

INSERT INTO Table2 (Col1, Col2)
SELECT Col1, Col2 FROM Table1

您可以调用命令对象来执行这些选项中的任何一个,ExecuteNonQuery

评论

0赞 Vector 11/14/2023
我还没有测试你的代码,但谢谢你 这是有道理的,当我偶然发现这个 AI 生成的代码时,我让它工作,但有一个例外:你只能传输一次数据,第二次尝试会给出一个 UNIQUE 错误 链接到代码,如果你想看一看,请参阅 codepal.ai/code-generator/query/A6Gi0C8e/...
0赞 jmcilhinney 11/14/2023
@Vector,这意味着您要添加两次相同的数据。不要。不过,这是一个不同的问题。如果您在尝试两次移动相同数据时失败,则意味着您已经成功移动了一次,因此您在此处实际询问的问题已得到解决。如果您想询问另一个问题,那么您需要发布一个新问题,其中包含所有且仅与该问题相关的信息。
0赞 Vector 11/14/2023 #2

尝试使用 ImportRow 是错误的工具。
也就是说,我正在尝试将数据存档在另一个表中,因此我的 DataGridView
仅显示 2 年的数据。一些性能增强。
下面是移动数据的代码和防止
用户两次移动相同数据的小例程。

    Private Sub DataPull()

    ' Represents a utility function for writing data from one table to another in the same database.
    '
    ' PARAMETERS:
    I()
    If count > 0 Then
        MessageBox.Show("That Year " + tbYear.Text + " Has Been Archived", "Warning", MessageBoxButtons.OK)
    End If
    Dim sourceTable As String = "TxData"
    Dim destinationTable As String = "TxArchiveData"

    ' EXCEPTION:
    ' Throws SqlException if there is an error executing the SQL query.

    Using conn As New SQLiteConnection($"Data Source = '{gv_dbName}';Version=3;")
        conn.Open()
        ' Create a SQL command to select all data from the source table.
        Using cmd As New SQLiteCommand("", conn)
            cmd.CommandText = $"SELECT * FROM {sourceTable} WHERE txYear =" & tbYear.Text
            ' Execute the select command and retrieve the data.
            Using rdr As SQLite.SQLiteDataReader = cmd.ExecuteReader
                ' Create a SQL command to insert the data into the destination table.
                Using cmd2 As New SQLiteCommand("", conn)
                    cmd2.CommandText = $"INSERT INTO {destinationTable} VALUES (@Column1, @Column2, @Column3,@Column4,@Column5)"
                    ' Prepare the insert command parameters.
                    cmd2.Parameters.Add("@Column1", DbType.Int64)
                    cmd2.Parameters.Add("@Column2", DbType.String)
                    cmd2.Parameters.Add("@Column3", DbType.String)
                    cmd2.Parameters.Add("@Column4", DbType.Int64)
                    cmd2.Parameters.Add("@Column5", DbType.Int64)

                    ' Loop through the data and insert it into the destination table.
                    While rdr.Read()
                        ' Set the parameter values.
                        cmd2.Parameters("@Column1").Value = rdr.GetInt64(0)
                        cmd2.Parameters("@Column2").Value = rdr.GetString(1)
                        cmd2.Parameters("@Column3").Value = rdr.GetString(2)
                        cmd2.Parameters("@Column4").Value = rdr.GetInt64(3)
                        cmd2.Parameters("@Column5").Value = rdr.GetInt64(4)

                        ' Execute the insert command.
                        cmd2.ExecuteNonQuery()
                        count = count + 1
                        tbInfo.Text = count.ToString
                    End While
                End Using
            End Using
            End Using
    End Using
End Sub
Private Sub I()
    Using conn As New SQLiteConnection($"Data Source = '{gv_dbName}';Version=3;")
        conn.Open()

        Using cmd As New SQLiteCommand("", conn)
            cmd.CommandText = "SELECT COUNT(*) FROM TxArchiveData WHERE txYear = " & tbYear.Text
            'Dim count As Integer Needs to be declard as toplevel variable
            'OR in a DataModule as gv_count it is used in DataPull() Sub
            cmd.Parameters.AddWithValue("@value", tbYear)
            count = CInt(cmd.ExecuteScalar())
        End Using
    End Using

End Sub