Foxtable(狐表)用户栏目专家坐堂 → 网络环境下复杂的不重复的编号生成技巧(升级版)


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

主题:网络环境下复杂的不重复的编号生成技巧(升级版)

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


加好友 发短信
等级:管理员 帖子:47448 积分:251054 威望:0 精华:91 注册:2008/6/17 17:14:00
网络环境下复杂的不重复的编号生成技巧(升级版)  发帖心情 Post By:2010/4/12 18:23:00 [只看该作者]

 下载信息  [文件大小:   下载次数: ]
点击浏览该文件:bianhao.rar


 

网络环境下的复杂编号


普通用户可以忽略本节内容。

本节内容可以参考上面的附件。

使用自动增量主键,例如_Identify列,能够有效解决编号的问题,即使是多人同时向一个表中增加行,也不会出现重复的编号。
但是自动增量主键只是一个数字,无法实现复杂的含有特殊信息的编号。
如果自己编码生成编号,如何避免在多人同时操作时产生重复的编号,是一个难题。

本节用一个简单的例子,来探讨如何解决这个问题。

本节的例子使用外部数据源,数据源文件为CaseStudy目录下的文件:编号.mdb
该文件只包括两个表,一个订单表,一个编号表。
希望订单表的编号能够自动生成,编号的格式为:0000-0000,左边四位为前缀,两位表示年,两位表示月,右边四位表示顺序号。
编号表并非常规的数据表,不加载到Foxtable中,而是直接通过SQL语句操作。
编号表包括两列,分别是:前缀和顺序号,前者为字符型,由两位年两位月组成,后者为整数型,用于保存此前缀的当前顺序号。


设计步骤:


1、因为订单表的编号列是主键列,所以在任何时候都不能为空,必须在增加行的时候,为新增行生成一个临时的编号,为此我们将订单表的DataRowAdding事件设置为:


Static Index
As Integer = 99999
e.
DataRow("编号") = Format(Date.Today(),"yyMM") & "-" & Index
Index = Index -
1


和正式的编号不同,临时编号的顺序号为5位,而且是从99999开始倒序编号,这样用户一看就知道这是临时的编号。


2、在保存的时候,为新增的行生成正式的编号,BeforeSaveDataRow事件代码设置为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Dim dr As DataRow = e.DataRow
Dim
pf As String
If
dr.RowState <> DataRowState.Added Then '如果不是新增行
   
Return '那么返回
ElseIf
dr.IsNull("日期") Then '如果没有输入日期
    e.Cancel =
True '取消保存此行
    MessageBox.Show(
"必须输入日期!","提示",MessageBoxButtons.OK,MessageBoxIcon.Information)
    Return
Else

    pf = Format(dr(
"日期"),"yyMM") '否则获得编号的前缀,两位年,两位月
End
If
Dim
cmd1 As New SQLCommand
Dim
cmd2 As New SQLCommand
Dim
Key As Integer
cmd1.ConnectionName =
"编号" '设置数据源名称
cmd2.ConnectionName =
"编号"
cmd1.commandText =
"Select Count(*) From [编号] Where [前缀] = '" & pf & "'"
If
cmd1.ExecuteScalar = 0 Then '如果编号表不存在前缀的行,那么增加一行
   
cmd1.commandtext = "Insert Into 编号 (前缀, 顺序号) Values('" & pf & "',1)"
   
cmd1.ExecuteNonQuery
End If

cmd1
.commandText = "Select [顺序号] From [编号] Where [前缀] = '" & pf & "'"
Do
    Key
= cmd1.ExecuteScalar() '从后台获得顺序号
    cmd2
.commandText = "Update [编号] Set [顺序号] = " & (Key + 1) & " Where [顺序号] = " & Key & " And [前缀] = '" & pf & "'"
    If
cmd2.ExecuteNonQuery() > 0 Then '更新顺序号
        Exit Do
'更新成功则退出循环
    End If
Loop

e.
DataRow("编号") = pf & "-" & Format(Key,"0000")


第10行代码获得编号的前缀(由两位年两位月组成),第17、18行代码判断编号表是否存在此前缀的记录,如果不存在,第19、20行代码则增加此前缀的记录,并将顺序号设置为1。
最关键的是第22到第30行代码,第24行代码首先从后台的编号表获得此前缀的顺序号,第26行代码尝试将该前缀的顺序号加1,如果操作成功则退出循环,并在第30行将前缀和顺序号组合成编号写入到要保存的行中。
那么在多人同时使用的时候,是如何避免重复的呢;假定A和B几乎同时执行了第24行代码,获得的顺序号相同,同样又几乎同时执行第26行代码,假定A用户抢先了一点,成功将该前缀的顺序号增加了1,随后B用户执行的时候,由于顺序号已经加1,所以Update语句的条件不符合,导致第26行的ExecuteNonQuery方法返回0,无法退出循环,于是B用户只能重复上述操作:获得顺序号,将顺序号加1,直到成功为止。

[此贴子已经被作者于2010-4-13 9:51:10编辑过]

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


加好友 发短信 一级勋章
等级:MVP荣誉狐 帖子:5154 积分:31434 威望:0 精华:8 注册:2008/9/8 12:27:00
  发帖心情 Post By:2010/4/12 18:49:00 [只看该作者]

收藏学习~

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


加好友 发短信 一级勋章
等级:超级版主 帖子:7235 积分:40556 威望:0 精华:16 注册:2008/8/31 23:23:00
  发帖心情 Post By:2010/4/12 19:46:00 [只看该作者]

半天不来,就有好东东,顶!

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


加好友 发短信
等级:三尾狐 帖子:754 积分:6991 威望:0 精华:1 注册:2008/9/2 20:04:00
  发帖心情 Post By:2010/4/12 20:05:00 [只看该作者]

正是我想学习的东西

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


加好友 发短信 F6
等级:狐精 帖子:3030 积分:19188 威望:0 精华:2 注册:2008/9/1 7:50:00
  发帖心情 Post By:2010/4/13 8:12:00 [只看该作者]

这可是第二个重磅,顶起!

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


加好友 发短信
等级:二尾狐 帖子:512 积分:4146 威望:0 精华:0 注册:2009/10/8 16:43:00
  发帖心情 Post By:2010/4/13 8:28:00 [只看该作者]

收藏学习


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


加好友 发短信
等级:幼狐 帖子:53 积分:1698 威望:0 精华:0 注册:2008/8/31 21:43:00
  发帖心情 Post By:2010/4/13 8:32:00 [只看该作者]

收藏学习~

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


加好友 发短信
等级:狐精 帖子:3313 积分:23134 威望:0 精华:1 注册:2009/3/31 11:25:00
  发帖心情 Post By:2010/4/13 9:22:00 [只看该作者]

收藏学习,非常好!

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


加好友 发短信
等级:管理员 帖子:47448 积分:251054 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2010/4/13 9:52:00 [只看该作者]

昨天的不够简洁,今天改进了一下,少了几行代码。

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


加好友 发短信
等级:幼狐 帖子:164 积分:2002 威望:0 精华:0 注册:2008/9/7 0:06:00
  发帖心情 Post By:2016/1/3 21:02:00 [只看该作者]


图片点击可在新窗口打开查看此主题相关图片如下:qq截图20160103205516.png
图片点击可在新窗口打开查看 我想编号用这样的规则行不,加入不同地区-类别,

如 QCDT-B1-2016-001  地区-类别-年份-序号

[此贴子已经被作者于2016/1/3 21:05:44编辑过]

 回到顶部