Foxtable(狐表)用户栏目专家坐堂 → 为什么在DataRowAdd或者DataColChanged获取的的Identify总是比实际的多了1?我想用这个identify作为不重复自动编号列用


  共有5893人关注过本帖树形打印复制链接

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

帅哥哟,离线,有人找我吗?
chen37280600
  1楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:六尾狐 帖子:1273 积分:7906 威望:0 精华:4 注册:2017/12/31 14:53:00
为什么在DataRowAdd或者DataColChanged获取的的Identify总是比实际的多了1?我想用这个identify作为不重复自动编号列用  发帖心情 Post By:2022/7/20 10:57:00 [只看该作者]


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


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


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


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

难道是access的机制问题?


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


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

 回到顶部
帅哥,在线噢!
有点蓝
  2楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:超级版主 帖子:109474 积分:557032 威望:0 精华:9 注册:2015/6/24 9:21:00
  发帖心情 Post By:2022/7/20 11:17:00 [只看该作者]

_Identify保存后才是正确的值

 回到顶部
帅哥哟,离线,有人找我吗?
chen37280600
  3楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:六尾狐 帖子:1273 积分:7906 威望:0 精华:4 注册:2017/12/31 14:53:00
  发帖心情 Post By: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编辑过]

 回到顶部
帅哥,在线噢!
有点蓝
  4楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:超级版主 帖子:109474 积分:557032 威望:0 精华:9 注册:2015/6/24 9:21:00
  发帖心情 Post By:2022/7/21 11:35:00 [只看该作者]

不是很合理,有并发问题,应该加上事务,然后在事务里,先更新编号为新值("Update 自动编号表 Set 当前编号 = 当前编号+1 Where 表名 = '" & tableName & "'",这时会锁定这行,其它人不会取到新值),再取新值

 回到顶部
帅哥哟,离线,有人找我吗?
chen37280600
  5楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:六尾狐 帖子:1273 积分:7906 威望:0 精华:4 注册:2017/12/31 14:53:00
  发帖心情 Post By: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编辑过]

 回到顶部
帅哥,在线噢!
有点蓝
  6楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:超级版主 帖子:109474 积分:557032 威望:0 精华:9 注册:2015/6/24 9:21:00
  发帖心情 Post By:2022/7/21 16:06:00 [只看该作者]

这种用法并发少没有什么

 回到顶部