VB6+Access2002-2003中AUTONUMBER字段偶尔无法生成值求助
解决Access Autonumber字段插入后无法稳定获取值的问题
问题根源
原有代码使用adOpenStatic游标打开空记录集后调用AddNew,这种方式依赖游标同步Autonumber值,但Access在轻量并发、缓存异常或数据库碎片积累时,可能无法即时返回生成的ID;而查询max(Progressivo_Tagliando)的方案会因并发插入导致获取到其他用户的ID,或因事务隔离级别问题出现数据不一致。
可靠解决方案
方案1:替换游标类型并强制刷新记录集
将游标类型改为adOpenKeyset,并添加强制刷新操作,确保自增ID被正确读取:
Dim adoTaglInserimentoRS As Recordset StmtInsert = "select * from Plico where Progressivo_Tagliando=0" ' 替换为adOpenKeyset游标,提升同步可靠性 adoTaglInserimentoRS.Open StmtInsert, db, adOpenKeyset, adLockOptimistic, adCmdText VarCampiTagliando = Array("Nota", "Progressivo_Distinta", "Data_Stato_Plico", "Progressivo_Destinatario", "Progressivo_Corriere", "Contenuto_Plico", "Rifpr_Numsin", "Progressivo_Tramite", "Stato_Plico", "Username_Inserimento", "Data_Inserimento") VarValoriTagliando = Array(adoTagliandoRSNote, adoTagliandoRSProgressivo_Distinta, adoTagliandoRSData_Stato_Plico, adoTagliandoRSProgressivo_Destinatario, adoTagliandoRSProgressivo_Corriere, adoTagliandoRSContenuto_Plico, adoTagliandoRSRifPr_NumSin, adoTagliandoRSProgressivo_Tramite, adoTagliandoRSStato_Plico, adoTagliandoRSUsername_Inserimento, adoTagliandoRSData_Inserimento) db.BeginTrans adoTaglInserimentoRS.AddNew VarCampiTagliando, VarValoriTagliando ' 强制刷新当前记录,确保Autonumber值加载 adoTaglInserimentoRS.Move 0 txtPrg_Tagliando.Text = adoTaglInserimentoRS!Progressivo_Tagliando adoTaglInserimentoRS.Close db.CommitTrans
方案2:使用Access内置@@IDENTITY函数(推荐)
@@IDENTITY会返回当前会话中最后插入记录的Autonumber值,不受游标类型影响,且不会被其他并发插入干扰:
Dim cmd As ADODB.Command Dim newID As Long db.BeginTrans ' 创建Command对象执行参数化插入 Set cmd = New ADODB.Command cmd.ActiveConnection = db cmd.CommandText = "INSERT INTO Plico (Nota, Progressivo_Distinta, Data_Stato_Plico, Progressivo_Destinatario, Progressivo_Corriere, Contenuto_Plico, Rifpr_Numsin, Progressivo_Tramite, Stato_Plico, Username_Inserimento, Data_Inserimento) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" ' 按字段顺序绑定参数 cmd.Parameters.Append cmd.CreateParameter("@Nota", adVarWChar, adParamInput, 255, adoTagliandoRSNote) cmd.Parameters.Append cmd.CreateParameter("@Progressivo_Distinta", adInteger, adParamInput, , adoTagliandoRSProgressivo_Distinta) cmd.Parameters.Append cmd.CreateParameter("@Data_Stato_Plico", adDate, adParamInput, , adoTagliandoRSData_Stato_Plico) cmd.Parameters.Append cmd.CreateParameter("@Progressivo_Destinatario", adInteger, adParamInput, , adoTagliandoRSProgressivo_Destinatario) cmd.Parameters.Append cmd.CreateParameter("@Progressivo_Corriere", adInteger, adParamInput, , adoTagliandoRSProgressivo_Corriere) cmd.Parameters.Append cmd.CreateParameter("@Contenuto_Plico", adVarWChar, adParamInput, 255, adoTagliandoRSContenuto_Plico) cmd.Parameters.Append cmd.CreateParameter("@Rifpr_Numsin", adVarWChar, adParamInput, 50, adoTagliandoRSRifPr_NumSin) cmd.Parameters.Append cmd.CreateParameter("@Progressivo_Tramite", adInteger, adParamInput, , adoTagliandoRSProgressivo_Tramite) cmd.Parameters.Append cmd.CreateParameter("@Stato_Plico", adVarWChar, adParamInput, 50, adoTagliandoRSStato_Plico) cmd.Parameters.Append cmd.CreateParameter("@Username_Inserimento", adVarWChar, adParamInput, 50, adoTagliandoRSUsername_Inserimento) cmd.Parameters.Append cmd.CreateParameter("@Data_Inserimento", adDate, adParamInput, , adoTagliandoRSData_Inserimento) ' 执行插入操作 cmd.Execute ' 获取刚生成的Autonumber值 Set cmd = New ADODB.Command cmd.ActiveConnection = db cmd.CommandText = "SELECT @@IDENTITY AS NewID" newID = cmd.Execute.Fields("NewID").Value txtPrg_Tagliando.Text = CStr(newID) db.CommitTrans Set cmd = Nothing
方案3:排查数据库本身问题
如果以上方案仍失效,需检查数据库状态:
- 压缩修复数据库:长期使用产生的碎片可能导致Autonumber异常,执行
工具>数据库实用工具>压缩和修复数据库。 - 验证字段属性:确保Progressivo_Tagliando字段的
新值属性为递增,未被误改为随机。 - 排查并发场景:若多用户同时操作该表,确认事务隔离级别设置合理,避免脏读或幻读。
内容的提问来源于stack exchange,提问作者giocap58
相关产品推荐
相关产品推荐

