关于编号增长的问题

Starbucks 2005-04-19 12:11:08
现在数据库里有一个字段,定义成一个varchar型,但是实际存放的是一个数字编号,为了唯一确定某一条记录。每插入一条新记录的时候,就先读出现在数据库中最大的,把最大的数字加一,然后再插回去,还要把这个数字给返回在页面上显示出来
现在的问题是,如何保证多个用户同时操纵的时候,两个用户得到的数字不会是相同的?因为两个用户可能读出相同的最大数值,然后再插入相同的就会出错。
如果使用每次要取最大的时候都先把数据库最大的+1然后更新,这样可能会导致该数字浪费的情况,因为用户读了数字之后可能不一定提交,也就是不一定插入这条记录

总之,就是又要避免浪费序号,又要避免多用户同时操作时的冲突?

使用vb.net的web application

哪位大虾给点意见,数据库设计上的修改也可以。。多谢了。。
...全文
260 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
dreamover 2005-05-02
  • 打赏
  • 举报
回复
用guid?
wyb0026 2005-04-30
  • 打赏
  • 举报
回复
我感觉应该编号在所有事情做完之后分配,不应该先取编号
chengpei_chen 2005-04-30
  • 打赏
  • 举报
回复
用insert触发器吧,可以解决问题的。
tdtjjiao 2005-04-30
  • 打赏
  • 举报
回复
用两个字段,一个IDENTITY,一个就是你那个编号,
你都说了各个地方用的号码的都不相同那就说明,一个地方的人就用一种编号
你可以设定一个配置文件,让用户输入第一个编号,然后你按照他的方式往下编,
你不要在做的时候就提取,要在INSERT的时候再查表找最大的那个号码,
hb9723 2005-04-30
  • 打赏
  • 举报
回复
可以新建一个表,记录表名和表中的记录数目,每次直接从该表获取记录数,并更改该表。
至于避免同时操作的问题,可以通过锁表来控制当前唯一可执行的操作。
yang_neusoft 2005-04-30
  • 打赏
  • 举报
回复
加锁
fiele 2005-04-26
  • 打赏
  • 举报
回复
你不能让他们读完了再取最大的吗?
mo_yuan_ming 2005-04-25
  • 打赏
  • 举报
回复
使用after insert 触发器吧!插就生一个新号!
alone1998 2005-04-25
  • 打赏
  • 举报
回复
若此号生成用户不看,而且系统又不用写入其他地方,(加锁)就取本表的要加一哪个字段的最大号,然后加一作为新号插入表(插入成功解锁)就可以了,若此列数据有字母等前缀,则按前缀分组取组内最大号加一,若不用考虑字母前缀就直接取数字部分的最大值加一就可以啊!若表中数据有删除导致空号则考虑是否重复利用空号,若利用也可以直接取(较复杂先不详述),不利用就更简单了,如上所述即可。这可以简单而优美的解决问题了
Starbucks 2005-04-25
  • 打赏
  • 举报
回复
to alone1998
请问你说的完美的解决办法是什么?是自增长的序列号么?:)
alone1998 2005-04-24
  • 打赏
  • 举报
回复
若先就必须把此号取出给用户看而且要求此号保存不变(若是自动编号应该没有这个需求),没有什么更好的方法;若此号是程序自动分配不用写到其他地方也没有用户干预,此问题有完美的解决方法。
Starbucks 2005-04-23
  • 打赏
  • 举报
回复
to jiang130 and hehe139
我现在想的基本想法就是这样
不过这样就不能预先知道id是多少,只有等插入记录以后才知道数据是多少
希望有更好的方法:)
Starbucks 2005-04-23
  • 打赏
  • 举报
回复
我现在的想法基本上就是读和写回最大值同时执行
利用一个单独的表来存储最大值
在读的时候把最大的数据加锁,然后写回去的时候再给释放
在打算往数据库里写的时候才去取最大值并更新最大值

现在只能这样了

别的不知道还有什么更好的方法?
jiang130 2005-04-20
  • 打赏
  • 举报
回复
各个网点之间的数据编号格式都不一样,前面会有一个前缀,但編號和identity列之間有聯系嗎?如果沒有方便的聯系﹐可以考慮用存儲過程讀最大數﹐但我認為只是在保存的那一刻才去讀最大數﹐用戶讀取時顯示的最大數很可能在保存時已不是最大數了(這個數讀取時一定要顯示出來嗎﹖)。

--再你讀出這個最大數的同時在最大數上+1 不可以嗎?
----------------------------------------------

多用戶操作時一個用戶讀出到保存有一段時間﹐這段時間內別的用戶讀到的數會不會一樣呢?

//保存時再讀數也可避免浪費
Navywang917 2005-04-20
  • 打赏
  • 举报
回复
按照你的要求浪费是不可避免的。我想用 前缀+当前时间+随机数 会好一点吧!
hebe139 2005-04-20
  • 打赏
  • 举报
回复
各个网点之间的数据编号格式都不一样,前面会有一个前缀,但編號和identity列之間有聯系嗎?如果沒有方便的聯系﹐可以考慮用存儲過程讀最大數﹐但我認為只是在保存的那一刻才去讀最大數﹐用戶讀取時顯示的最大數很可能在保存時已不是最大數了(這個數讀取時一定要顯示出來嗎﹖)。

--再你讀出這個最大數的同時在最大數上+1 不可以嗎?
xluzhong 2005-04-20
  • 打赏
  • 举报
回复
@@IDENTITY
返回最后插入的标识值。

语法
@@IDENTITY

返回类型
numeric

注释
在一条 INSERT、SELECT INTO 或大容量复制语句完成后,@@IDENTITY 中包含此语句产生的最后的标识值。若此语句没有影响任何有标识列的表,则 @@IDENTITY 返回 NULL。若插入了多个行,则会产生多个标识值,@@IDENTITY 返回最后产生的标识值。如果此语句激发一个或多个执行产生标识值的插入操作的触发器,则语句执行后立即调用 @@IDENTITY 将返回由触发器产生的最后的标识值。若 INSERT 或 SELECT INTO 语句失败或大容量复制失败,或事务被回滚,则 @@IDENTITY 值不会还原为以前的设置。

在返回插入到表的 @@IDENTITY 列的最后一个值方面,@@IDENTITY、SCOPE_IDENTITY 和 IDENT_CURRENT 函数类似。

@@IDENTITY 和 SCOPE_IDENTITY 将返回在当前会话的所有表中生成的最后一个标识值。但是,SCOPE_IDENTITY 只在当前作用域内返回值,而 @@IDENTITY 不限于特定的作用域。

IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回任何会话和任何作用域中为特定表生成的标识值。有关更多信息,请参见 IDENT_CURRENT。

示例
下面的示例向带有标识列的表中插入一行,并用 @@IDENTITY 显示在新行中使用的标识值。

INSERT INTO jobs (job_desc,min_lvl,max_lvl)
VALUES ('Accountant',12,125)
SELECT @@IDENTITY AS 'Identity'
jiang130 2005-04-20
  • 打赏
  • 举报
回复
各个网点之间的数据编号格式都不一样,前面会有一个前缀,但編號和identity列之間有聯系嗎?如果沒有方便的聯系﹐可以考慮用存儲過程讀最大數﹐但我認為只是在保存的那一刻才去讀最大數﹐用戶讀取時顯示的最大數很可能在保存時已不是最大數了(這個數讀取時一定要顯示出來嗎﹖)。
friendliu 2005-04-19
  • 打赏
  • 举报
回复
可以建一个临时变量存储或者写一个存府过程返回当时的最大数

这样每次更新之前直接去读这个最大数

这样可以提高效率

对于多个用户同时更新的情况,可以用事务控制和加锁来实现保持数据库的一致性
soglad 2005-04-19
  • 打赏
  • 举报
回复
这个问题比较难的说,我也考虑好长时间了,但是没有好的办法,关注中!
加载更多回复(2)

27,580

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧