如何获取链接到MySQL的Access中的auto_increment字段的值?
我正试图修改现有的Access应用程序,通过ODBC将MySQL用作数据库,并且只需最少的重新编码 当前代码通常会使用DAO插入新记录,然后使用LASTMODIFED获取ID。这不适用于MySQL。相反,我尝试使用如何获取链接到MySQL的Access中的auto_increment字段的值?,mysql,ms-access,Mysql,Ms Access,我正试图修改现有的Access应用程序,通过ODBC将MySQL用作数据库,并且只需最少的重新编码 当前代码通常会使用DAO插入新记录,然后使用LASTMODIFED获取ID。这不适用于MySQL。相反,我尝试使用 SELECT * FROM tbl_name WHERE auto_col IS NULL 建议在中访问。但是,如果我设置一个只包含id和文本数据字段的示例表并执行 CurrentDb.Execute ("INSERT INTO tbl_scratch (DATA) VALUES
SELECT * FROM tbl_name WHERE auto_col IS NULL
建议在中访问。但是,如果我设置一个只包含id和文本数据字段的示例表并执行
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文档给出了检索id的SQL语句作为一个在Access中工作的示例(正如它声明的LAST_INSERT_id()不工作),但没有给出进一步的细节
我该如何解决这个问题?解决(并写博客)如下
我一直在对一组Access数据库进行升级,用ODBC链接的MySQL替换Access文件数据库。除了将记录插入到具有自动递增id列的表中并检索刚刚创建的id值这一常见概念之外,一切似乎都进展得非常顺利。当然,在PHP或类似的应用程序上,只需使用
选择最后一个插入ID()
函数来检索ID。但是MySQL文档本身说这不适用于某些ODBC应用程序,如Delphi或Access,并建议使用
从tbl中选择*其中auto为空
不幸的是,当从我正在使用的Access应用程序内部调用时,这对我来说根本不起作用,而且web上似乎有一些评论认为这确实不可靠,因为Access可能会中断数据连接并在幕后重新连接,从而使调用无效
作为替代方案,我决定使用MySQL函数向表中添加一条空白记录,返回Access随后用于更新记录的id(这与现有应用程序的代码样式非常吻合)。不幸的是,这种看似简单的解决方法也不简单,因为MySQL中长期存在的bug使得寻找既能发送又能返回变量的有效代码成为一种挑战。web上的几个示例将在使用just-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不兼容),上面的代码似乎是允许传递和返回两个数据的唯一方法。解决(并写日志)如下所示
我一直在对一组Access数据库进行升级,用ODBC链接的MySQL替换Access文件数据库。除了将记录插入到具有自动递增id列的表中并检索刚刚创建的id值这一常见概念之外,一切似乎都进展得非常顺利。当然,在PHP或类似的应用程序上,只需使用
选择最后一个插入ID()
函数来检索ID。但是MySQL文档本身说这不适用于某些ODBC应用程序,如Delphi或Access,并建议使用
从tbl中选择*其中auto为空
不幸的是,当从我正在使用的Access应用程序内部调用时,这对我来说根本不起作用,而且web上似乎有一些评论认为这确实不可靠,因为Access可能会中断数据连接并在幕后重新连接,从而使调用无效
作为替代方案,我决定使用MySQL函数向表中添加一条空白记录,返回Access随后用于更新记录的id(这与现有应用程序的代码样式非常吻合)。不幸的是,这种看似简单的解决方法也不简单,因为MySQL中长期存在的bug使得寻找既能发送又能返回变量的有效代码成为一种挑战。web上的几个示例将在使用just-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不兼容),上述方法似乎是允许传递和返回两个数据的唯一方法