以文本方式查看主题

-  Foxtable(狐表)  (http://foxtable.net/bbs/index.asp)
--  专家坐堂  (http://foxtable.net/bbs/list.asp?boardid=2)
----  为什么在DataRowAdd或者DataColChanged获取的的Identify总是比实际的多了1?我想用这个identify作为不重复自动编号列用  (http://foxtable.net/bbs/dispbbs.asp?boardid=2&id=178775)

--  作者:chen37280600
--  发布时间:2022/7/20 10:57:00
--  为什么在DataRowAdd或者DataColChanged获取的的Identify总是比实际的多了1?我想用这个identify作为不重复自动编号列用

图片点击可在新窗口打开查看此主题相关图片如下:qq截图20220720105554.png
图片点击可在新窗口打开查看


为什么在DataRowAdd或者DataColChanged获取的的Identify总是比实际的多了1?我想用这个identify作为不重复自动编号列用


图片点击可在新窗口打开查看此主题相关图片如下:2.png
图片点击可在新窗口打开查看


图片点击可在新窗口打开查看此主题相关图片如下:3.png
图片点击可在新窗口打开查看

难道是access的机制问题?


图片点击可在新窗口打开查看此主题相关图片如下:4.png
图片点击可在新窗口打开查看


难道在局域网多人下,不上服务器端这个“中间商”,就永远没办法折腾出这个靠谱的自增数字?
[此贴子已经被作者于2022/7/20 11:12:26编辑过]

--  作者:有点蓝
--  发布时间:2022/7/20 11:17:00
--  
_Identify保存后才是正确的值
--  作者:chen37280600
--  发布时间:2022/7/21 10:58:00
--  
好的,参考帮助文档《网络环境下的复杂编号》,思路相同,分享我在局域网下自动编号更精简的代码:
1.建立记录自动编号的表,名称:自动编号表

图片点击可在新窗口打开查看此主题相关图片如下:2.png
图片点击可在新窗口打开查看


2.内部函数名:获取自动编号
\'通过Functions.Execute("获取自动编号","表名")使用
\'传入表名,返回这个表当前可用的新自增编号
\'思路参考狐表官方文档《网络环境下的复杂编号》,实测异步并发生成也不会有重复编号

Dim tableName As String = Args(0)

Dim cmd As New SQLCommand
cmd.Co nnecti 
cmd.commandText = "Sel ect Count(*) From 自动编号表 Where 表名 = \'" & tableName & "\'"
If cmd.ExecuteScalar = 0 Then \'如果编号表不存在该表名的记录,那么增加一行
    cmd.commandtext = "Ins ert Into 自动编号表 (表名, 当前编号) Values(\'" & tableName & "\',1)"
    cmd.ExecuteNonQuery
End If

Dim No As Integer
Do
    cmd.commandText = "Sel ect 当前编号 From 自动编号表 Where 表名 = \'" & tableName & "\'" 
    No = cmd.ExecuteScalar() \'从后台获得当前编号
    cmd.commandText = "Upd ate 自动编号表 Set 当前编号 = " & (No + 1) & " Where 当前编号 = " & No & " And 表名 = \'" & tableName & "\'"
    If cmd.ExecuteNonQuery() > 0 Then \'更新编号
        Exit Do \'更新成功,说明编号可用,则退出循环
    End If
Loop
Return No

3.在业务表的DataRowAdding事件
e.DataRow("编号") = Functions.Execute("获取自动编号", e.DataTable.Name)

4.即可得到以下效果

图片点击可在新窗口打开查看此主题相关图片如下:自增编号效果.png
图片点击可在新窗口打开查看
[此贴子已经被作者于2022/7/21 11:18:25编辑过]

--  作者:有点蓝
--  发布时间:2022/7/21 11:35:00
--  
不是很合理,有并发问题,应该加上事务,然后在事务里,先更新编号为新值("Update 自动编号表 Set 当前编号 = 当前编号+1 Where 表名 = \'" & tableName & "\'",这时会锁定这行,其它人不会取到新值),再取新值
--  作者:chen37280600
--  发布时间:2022/7/21 15:10:00
--  

图片点击可在新窗口打开查看此主题相关图片如下:重复.png
图片点击可在新窗口打开查看



图片点击可在新窗口打开查看此主题相关图片如下:测试结果.png
图片点击可在新窗口打开查看


图片点击可在新窗口打开查看此主题相关图片如下:重复2.png
图片点击可在新窗口打开查看

最多会遇到一种异常,但是也不会重复,不重复就行了:
行被锁定,无法更新

所以更新一下自定义内部函数的代码,增加个Try规避锁定导致的循环中止

\'通过Functions.Execute("获取自动编号","表名")使用
\'传入表名,返回这个表当前可用的新自增编号
\'思路参考狐表官方文档《网络环境下的复杂编号》,实测异步并发生成也不会有重复编号

Dim tableName As String = Args(0)

Dim cmd As New SQLCommand
cmd.Con nec tionNa me = "DB" \'数据库源名称 
cmd.commandText = "Sele ct Count(*) From 自动编号表 Where 表名 = \'" & tableName & "\'"
If cmd.ExecuteScalar = 0 Then \'如果编号表不存在该表名的记录,那么增加一行
    cmd.commandtext = "Inse rt Into 自动编号表 (表名, 当前编号) Values(\'" & tableName & "\',1)"
    cmd.ExecuteNonQuery
End If

Dim No As Integer 
Do
    \'1从后台获取当前最新编号
    cmd.commandText = "Sele ct 当前编号 From 自动编号表 Where 表名 = \'" & tableName & "\'" 
    No = cmd.ExecuteScalar()

    \'2尝试更新编号,确保编号可用
    cmd.commandText = "Upd ate 自动编号表 Set 当前编号 = " & (No + 1) & " Where 当前编号 = " & No & " And 表名 = \'" & tableName & "\'"
    Try \'超过数据库并发承受力,会出现“行被锁定,无法更新”,要能捕获错误并跳过继续尝试
        If cmd.ExecuteNonQuery() > 0 Then \'更新编号
            Exit Do \'更新成功,说明编号可用,则退出循环
        End If
    Catch ex As Exception
    End Try
Loop 

Return No
[此贴子已经被作者于2022/7/21 15:29:33编辑过]

--  作者:有点蓝
--  发布时间:2022/7/21 16:06:00
--  
这种用法并发少没有什么