天天看点

机房收费系统:(三)SQLSever中自增长ID问题

       在本次机房收费系统中,数据库的用户增加过程中需要将每个增加的用户给一个自增长的序列号,这就考虑到数据库和vb的交互过程,甚至我们会遇到在写数据库程序的时候,经常会需要获取某个表中的最大序号数,查询资料找了几个方法,解决问题。

一般情况下获取刚插入的数据的id,使用select max(id) from table 是可以的。但在多线程情况下,就不行了。

(1) getgeneratedkeys()方法:

     程序片断:

        connection conn=...;

        serializable ret = null;

        preparedstatement  state=  conn.preparestatement(sql,statement.return_generated_keys);

        resultset rs=null;

        try {

            state.executeupdate();

            rs = state.getgeneratedkeys();

            if (rs.next()) {

                ret = (serializable) rs.getobject(1);

            }       

        } catch (sqlexception e) {

        } 

        return ret;

(2)last_insert_id方法:

    last_insert_id 是与table无关的,如果向表a插入数据后,再向表b插入数据,last_insert_id会改变。

在多用户交替插入数据的情况下max(id)显然不能用。

    这就该使用last_insert_id了,因为last_insert_id是基于connection的,只要每个线程都使用独立的connection对象,last_insert_id函数将返回该connection对auto_increment列最新的insert or update*作生成的第一个record的id。这个值不能被其它客户端(connection)影响,保证了你能够找回自己的 id 而不用担心其它客户端的活动,而且不需要加锁。使用单insert语句插入多条记录,  last_insert_id返回一个列表。

(3)select @@identity方法:

    string sql="select @@identity";

    @@identity是表示的是最近一次向具有identity属性(即自增列)的表插入数据时对应的自增列的值,是系统定义的全局变量。一般系统定义的全局变量都是以@@开头,用户自定义变量以@开头。比如有个表a,它的自增列是id,当向a表插入一行数据后,如果插入数据后自增列的值自动增加至101,则通过select @@identity得到的值就是101。使用@@identity的前提是在进行insert操作后,执行select

@@identity的时候连接没有关闭,否则得到的将是null值。

   通过上面三种方法,可以解决sql中增加新用户中自增长的问题以及sql中查询数据的id。