如何在链接到MySQL的Access中获取自动增量字段的值?

时间:2010-03-23 23:02:21

标签: mysql ms-access

我正在尝试修改现有的Access应用程序,以便通过ODBC将MySQL用作数据库,并且记录的次数最少。

当前代码通常会使用DAO插入新记录,然后使用LastModified获取ID。这不适用于MySQL。相反,我正在尝试使用

方法
SELECT * FROM tbl_name WHERE auto_col IS NULL

建议MySQL documentation中的访问权限。但是,如果我设置一个仅包含id和text数据字段的示例表并执行此

CurrentDb.Execute ("INSERT INTO tbl_scratch (DATA) VALUES ('X')")
Set rst = CurrentDb.OpenRecordset("SELECT id FROM tbl_scratch WHERE id IS NULL")
myid = rst!id

ID返回null。但是,如果我执行

INSERT INTO tbl_scratch (DATA) VALUES ('X');
SELECT id FROM tbl_scratch WHERE id IS NULL;

使用直接MySQL编辑器然后正确返回id,所以我的数据库和方法很好,但我在Access中的实现必须是不正确的。令人沮丧的是,MySQL文档提供了SQL语句来检索id作为在Access中工作的示例(因为它声明LAST_INSERT_ID()没有)但没有提供进一步的细节。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

解决(和博客)如下

我一直在为一组Access数据库实现升级,以使用ODBC链接的MySQL替换Access文件数据库。除了将记录插入具有自动增量id列的表并检索刚创建的id的值的常见概念之外,一切似乎都非常顺利。当然,对于PHP等,只需使用

即可

SELECT LAST_INSERT_ID()

检索ID的功能。但是,MySQL文档本身表示这不适用于某些ODBC应用程序,如Delphi或Access,并建议使用

SELECT * FROM tbl WHERE auto IS NULL;

不幸的是,当我从我正在使用的Access应用程序内部调用时,这对我来说根本不起作用,并且在Web上似乎有几条评论确实这是不可靠的,因为Access可能会丢弃数据连接并重新连接到场景 - 从而使通话无效。

作为替代方案,我决定使用MySQL函数向表中添加空白记录,返回Access然后用于更新记录的id(这与现有应用程序的代码样式非常吻合)。不幸的是,这显然简单的解决办法也不是很简单,因为MySQL中长期存在的错误使得找到有效的代码可以发送和返回变量。 Web上的几个示例将在仅使用IN或OUT变量的有限域内工作,但无法同时使用这两个变量。

我的最终解决方案,适用于我正在部署的MySQL 5.1和Access 2003组合,如下所示

MySQL程序

DELIMITER $$

CREATE
    PROCEDURE `alicedata`.`sp_ins_identity`(IN tablename VARCHAR(50))
    BEGIN
    SET @result = 0;
    SET @sqlproc = CONCAT("INSERT INTO ",tablename," () VALUES ();");
    PREPARE s1 FROM @sqlproc;
    EXECUTE s1;
    DEALLOCATE PREPARE s1;
    SELECT LAST_INSERT_ID();
    END$$

此过程很有用,因为它将插入一行并返回任何表的id,其中一行包含所有空字段或定义了默认值的非空字段。要调用它,我使用以下函数:

Public Function InsertMySQLIdentityRow(DSN As String, Tablename As String) As Integer
On Error GoTo Err_InsertMySQLIdentity

Dim cnnSQL As New ADODB.Connection
Dim cmdSQL As ADODB.Command
Dim pid As Integer
Dim rs
Dim strSQL As String

    ' initialize
    pid = 0

    ' set up ADO connection
    Set cnnSQL = New ADODB.Connection
    cnnSQL.Open DSN

    ' execute the procedure - note that assembling by parameter fails to handle IN or OUT correctly

    Set cmdSQL = New ADODB.Command
    cmdSQL.ActiveConnection = cnnSQL

    strSQL = "call sp_ins_identity('" & Tablename & "');"
    Set rs = CreateObject("ADODB.Recordset")
    Set rs = cnnSQL.Execute(strSQL)

    If Not rs.EOF Then
      pid = rs(0)
    End If

    ' clean up
    Set rs = Nothing
    Set cmdSQL = Nothing
    cnnSQL.Close
    Set cnnSQL = Nothing

Exit_InsertMySQLIdentity:
    InsertMySQLIdentityRow = pid
    Exit Function

Err_InsertMySQLIdentity:
    MsgBox Err.Number & Err.Description
    Resume Exit_InsertMySQLIdentity
End Function

这段代码有点不寻常,因为通常在MSSQL上你会使用参数化过程调用,但是由于MySQL ODBC中的错误(或者至少与Access不兼容),上面似乎是允许两者的唯一方法要传递和返回的数据。