您的位置:程序门 -> vb -> 基础类



如何在插入记录之前预先获取自动+1类型字段的取值?


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


如何在插入记录之前预先获取自动+1类型字段的取值?
发表于:2007-05-22 07:50:41 楼主
有一个字段类型为自动+1,如何在一次插入记录之前预先获取该字段的取值应该是多少?
发表于:2007-05-22 08:13:331楼 得分:0
方法一:
access里,设置个自动编号类型的字段,
sql   server里,把标识设为true,然后标识递增设为1
这样数据库会自动处理,   不需要在sql语句里设这个字段的值了

二:
在每次插入前,   select   max(field1)   from   tab   [here   field2=]
然后+1作为更新,
发表于:2007-05-22 08:35:522楼 得分:0
既然是自动加   1   ,何必去理会它?
发表于:2007-05-22 09:35:363楼 得分:0
不需要预先知道吧!自动+1的目的就是为了解决并发用户同时操作的,有必要预先知道吗?
发表于:2007-05-22 10:33:254楼 得分:0
就是有必要预先知道啊,比如说我要新建一个科室,科室的id是自动+1的,新建科室的名称要自动成为   "新建科室 "   +   当前编号


我想既然sql数据库可以处理每个表的自动+1字段值,他应该是把当前最大值存储在了某个地方
发表于:2007-05-22 10:41:105楼 得分:0
本身理解就有问题了。科室名称与id无关,就算是科室编号也是与id无关的。之所以用id目的就要唯一性啊!所以你再想想...
发表于:2007-05-22 10:59:456楼 得分:0
科室名称是与id无关,科室编号就是id!!
科室名称在新建的时候是默认名称为   “新建科室”   +   id   的,这样就有关了吧
发表于:2007-05-22 11:16:397楼 得分:0
还是思路问题!再想想看。科室编号用id,本身就不合理了。
发表于:2007-05-22 11:39:538楼 得分:0
晕,我设计表格的时候,很多唯一编号都是用的自动id
这样不好吗?有什么不好咯
发表于:2007-05-22 11:46:449楼 得分:0
id是id,编号是编号,两者混为一谈就是错了。不想多说,自己想吧!
发表于:2007-05-22 13:18:2510楼 得分:0
我想知道为什么不能用自动id作为编号,有想说的进来说一下,不要牛b叉叉的样子

回到原来的问题,到底有办法预先获取取值是多少吗
发表于:2007-05-22 13:33:5211楼 得分:0
网上找来的,你可以试一下

自jet4.0以后,jet提供了对 "select   @@identity "这条语句的支持,我们一般在数据库中插入记录有两种方法,其一是使用addnew和update,其二是使用insert   into语句。

1、insert   into语句后,如何取自动编号的值,请看例程:
cnn.EXECute   "insert   into   goods   (name,description)   values   ( '新商品1 ', '新商品描述1 ') "
dim   rst   as   adodb.recordset
set   rst=new   adodb.recordset
rst.open   "select   @@identity "
msgbox   rst(0)   '这里rst(0)即为新记录的自动编号字段的值

2、addnew和update执行后,如何取自动编号的值,请看例程:
rst.addnew
rst.fields( "name ")= "新商品1 "
rst.fields( "description ")= "新商品描述1 "
rst.update
msgbox   rst.fields( "id ")   '这里rst.fields( "id ")即为新记录的自动编号字段的值,注意,id是我在goods表中设计的自动编号列名。

下   面说说其中涉及到的一些知识,jet4.0以后支持select   @@identity语句,这条语句执行后会返回执行这条语句的connection对象最近一次插入的记录中的自动编号字段的值。当使用update方   法时,jet引擎自动把它转换成insert语句,并且还要自动调用一次select   @@identity查询,这就是为什么在update后,不需要使用select   @@identity就可以直接获得自动编号的值的原因。

值得注意的是,插入操作和执行select   @@identity的操作所使用的connection对象应该是同一个对象。

其实这就是微软给出的方法,我为什么还要在这里再啰嗦一次呢,原因是,我在测试上面的两个方法时,update可以,但insert那个方法总是得到0。我很疑惑,仔细看了例程后,发现例程中的数据库是使用adox的catalog对象创建的,其方法是:
cat.create   "provider=microsoft.jet.oledb.4.0;data   source=c:\newjet4.mdb; "

要   知道,如果使用上面的语句创建出来的数据库其实是access2000格式的,而我常常喜欢在visdata中操作数据库,visdata创建的数据库是   access95格式的,而在微软support中提到了,对select   @@identity语句的支持是在access2000后才得到提供的,这就是我测试通不过的原因。

另外对于使用visdata或者   access95格式的数据库,使用上面提到的第2种方法获取自动编号的值有时正常,有时却返回0,这要看数据库更新的速度了,如果数据库没来得及更新,   你就查询自动编号字段的值,得到的就会是0了,所以说,对于access95格式的数据库来说,这种方法是存在隐患的。更直接的说,我和你都应该抛弃   visdata和access95了。

另外再说一点题外话,使用adox创建access95格式,也就是visdata可以打开的数据库的方法是:
cat.create   "provider=microsoft.jet.oledb.4.0;data   source=c:\newjet4.mdb;extended   properties= 'jet   3.x '; "

这里针对使用access95格式数据库的兄弟再提供一个办法,也是上面的support中提过的,那就是使用bookmark和absoluteposition,请看例程:

3、使用access95格式数据库如何获取新插入记录的自动编号的值:
rst.addnew
rst.fields( "name ")= "新商品1 "
rst.fields( "description ")= "新商品描述1 "
rst.update
dim   bookmark   '这里bookmark应该是variant类型
bookmark   =   rst.absoluteposition
rst.requery   '这是一个重点
rst.absoluteposition   =   bookmark
msgbox   rst.fields( "id ")   '这里rst.fields( "id ")即为新记录的自动编号字段的值。

在这里,bookmark标识了新记录在rst的物理行位置,requery使rst得到更新,然后通过bookmark使rst的游标指向新记录,这种方法对于access95和

access2000的数据库都适用,它的缺点就是,你必须要requery,而有时我们的代码可能不想这样。

另外,方法1和方法2和方法3对于sql   server来说也是一样可以正常使用的,只要你确定jet的版本等于4.0。

再说一句题外话,如何确定jet版本呢,同样来自support,请看例程:
if   cnn.properties( "jet   oledb:engine   type ").value   =   5   then
msgbox   "jet   4.0   database "
else
msgbox   "not   a   jet   4.0   database "
end   if
发表于:2007-05-22 13:52:2812楼 得分:0
其实不需要预先知道的,你只要先插入,然后再更新一遍数据库数据,把科室名和自增长拼接一下就可以了
发表于:2007-05-22 20:11:1513楼 得分:0
在每次插入前,   select   max(自动id字段名)+1   from   yourtable  

发表于:2007-05-22 20:13:4314楼 得分:0
但如果曾经有删除操作并想将新的记录填补删除后的空位则要另外修改,麻烦一点。
发表于:2007-05-22 22:17:2115楼 得分:0
一般把此字段设定为自动型同时设为主键!
那么按此字段排序后,此表的最后一个记录就是最大的记录号了!
或者用楼上的,select   max(id)   from   表
re![id]+1就是你要的编号了!
发表于:2007-05-22 22:20:3816楼 得分:0
select   max(自动id字段名)+1   from   yourtable


快速检索

最新资讯
热门点击