使用主键复制 Access 表

Posted

技术标签:

【中文标题】使用主键复制 Access 表【英文标题】:Copy Access table with primary keys 【发布时间】:2021-10-18 16:11:32 【问题描述】:

使用 C#、ODBC 和 Jet 4.0 引擎来处理(旧的)Access 数据库。该任务要求我不使用 DAO。

遗憾的是,Microsoft Jet 4.0 数据库引擎不支持“RENAME”关键字。以下所有内容都会引发异常:

将表旧名称重命名为新名称; 将旧名称重命名为新名称; ALTER TABLE old_name 重命名为 new_name;

但以下语法确实有效:

SELECT * INTO new_name FROM old_name;

问题是没有复制主键。

有没有办法创建一个表的副本,并在副本中保留哪些字段是主键?

【问题讨论】:

呃... 任务要求我不使用DAO,为什么? DAO 与 Access 数据库引擎一起提供,因此如果您可以进行 ODBC 连接,则通常可以使用 DAO,而 Access 对 DDL 的支持有限,对于许多操作都需要 DAO。 谢谢@ErikA。这很可能是一个糟糕的要求!我们的目标是创建一个通用接口,使我们能够同时支持 Access 和其他数据库类型,如 mysql。这里的高级开发人员已经设定了我们根本不使用 DAO 的要求。因此,如果可能的话,我会尝试在原始 SQL 和 ODBC 驱动程序中执行此操作。我现在可以使用 ODBC 在原始 SQL 中做几乎所有事情。如果没有 DAO,这项特别的任务真的是不可能的,那么了解这一点将非常有价值! 【参考方案1】:

使用 ODBC,您可以获取/获取索引。大多数时候,PK 列都有一个称为主键的索引。这不是 100% 保证的。

所以,这在“大部分”时间里都有效:

例如:

Sub Test22()

    Using con As New OdbcConnection(My.Settings.Test44ODBC2)
        '            Using cmdSQL As New OdbcCommand("SELECT TOP 1 * From PKTEST", con)

        con.Open()

        Dim schemaTable As New DataTable
        schemaTable = con.GetSchema("Indexes", New String() Nothing, Nothing, "PKTEST")
        Me.DataGridView1.DataSource = schemaTable

    End Using

 End Sub

输出:

但是,用户可以创建索引并为其指定不同的名称。

因此,例如,我可以进入上表,并将主键重命名为我想要的任何内容 - 这么说:

所以,不是很好。

但是,虽然应用程序和“大部分”代码可能会坚持使用 ODBC?

如果您使用 oleDB,那么您可以 100% 可靠地获得 PK,并且您不必参考 DAO。

因此,虽然上面显示我们将 PK 重新命名为末尾的“zoo”,但此 oleDB 代码仍将返回 PK 列,如下所示:

Sub GetoleDBGetKey()

    Using con As New OleDbConnection(My.Settings.TESTAce)
        Using cmdSQL As New OleDbCommand("SELECT * from PKTEST", con)

            con.Open()
            Dim schemaTable As DataTable = con.GetOleDbSchemaTable(OleDbSchemaGuid.Primary_Keys,
                            New Object() Nothing, Nothing, "PKTEST")

            Me.DataGridView1.DataSource = schemaTable
        End Using
    End Using
End Sub

所以,oleDB 将 100% 工作。

上面的 ODBC 片段?好吧,我们将不得不假设“PrimaryKey”,这并不是真正的要求(它是/被命名为“PrimaryKey”)

所以,你可以考虑 oleDB。

我没有深入挖掘,但我认为 ODBC 不能可靠地获得 PK。

您可以使用我上面的 odbc getSchema。有一些代码片段建议您打开连接,打开阅读器并使用数据阅读器的 getchema,并且确实可以工作-但我没有工作示例(甚至不知道这是否可以工作-但是有有些人认为这可以/确实有效)。

【讨论】:

这可以适应我的需要,谢谢!我已经测试了OdbcConnection::GetSchema。在我正在查看的表中,所有主键仍命名为“PrimaryKey”,因此 ODBC 将起作用。但是感谢您的评论,如果索引已重命名,则不能保证...注意!还测试了OleDbConnection::GetOleDbSchemaTable,这完全符合建议。 如前所述,有些人建议针对 odbc 阅读器的 getSchema 可以工作,但我并没有超越获取索引。 odbc 的架构中有一个主键标志,但不幸的是它没有设置。主键可能没问题,但如前所述,这是一个不是 100% 的假设。此外,在第一个代码片段中,不需要创建命令对象 - 这只是我拥有的一些代码的剪切 + 粘贴。

以上是关于使用主键复制 Access 表的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Access 希望您识别链接表上的主键?

MS ACCESS - 如何使用查询生成表添加主键

将自动递增的主键插入 Access 表

从一个 Access 数据库复制到另一个 (VBA)

在ACCESS创建表的五种方法

Excel VBA:将表数据导出到 Access。如果 2 个字段的主键已经存在,如何覆盖?