解決(和博客),如下
我已經實現了一組Access數據庫來取代MySQL的訪問文件數據庫通過ODBC連接的升級。除了將記錄插入帶有自動增量id列的表格並檢索剛剛創建的ID的值的常見概念之外,一切似乎都非常順利。當然,在PHP或類似的人會只使用
SELECT LAST_INSERT_ID()
函數來檢索ID。然而,MySQL文檔本身說,這不適用於某些ODBC應用程序,如Delphi或Access,並建議使用
SELECT * FROM tbl WHERE auto IS NULL;
不幸的是,從我正在使用的Access應用程序內部進行調用時,這似乎不起作用,並且似乎在網絡上出現了幾條評論,確實這是不可靠的,因爲Access可能丟棄數據連接並重新連接場景 - 從而使通話無效。
作爲替代方案,我決定使用MySQL函數向表中添加空白記錄,並返回Access用於更新記錄的ID(這與現有應用程序的代碼風格非常吻合)。不幸的是,這種明顯簡單的解決方法並不簡單,要麼是因爲MySQL中長期存在的錯誤會發現有效的代碼,可以發送和返回變量都是一種挑戰。網絡上的幾個例子可以在使用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(錯誤或至少不兼容性訪問)上述似乎是允許這兩個數據傳遞和返回的唯一方法。