例如A操作者用Insert加入记录到一个表之后,紧跟后面加上select @@identity可以把加入的标志列的编号取出来。
但因为是在服务器做这个insert和select的动作,而且是用两个方法(在JAVA中,用executeUpdate(insert into...)和executeQuery(select @@identity)来做的。虽然是用了事务,并且是紧接着的两行代码,但我还总是担心,中间会被另一个B操作者插入了另一行的记录,而造成executeQuery的结果错误。
不知道我的这个担心是否多余。
我自己想了另一行代码,select @@identity(select max(sn) from tableName where ....),这样应该就可以保证A操作者取得那个标志列的编号了。不知道我的想法对不对。另外,我还是问一下:JAVA里面,有没有一个方法,可以直接取得那个新增加的记录的标志列的编号,因为在T-SQL的范例里面,本来就是这样写的:insert into tableName values(....);select @@identity,那么,这个方法就可以这样写:
方法名("insert into tableName values(....);select @@identity")
这样,我就觉得可以肯定,取得的这个数字,就是刚增加的那条记录的编号了。

解决方案 »

  1.   

    不好意思,有段话写错了,应该是:
    我自己想了另一行代码,executeQurey(select max(sn) from tableName where ....),这样应该就可以保证A操作者取得那个标志列的编号了。不知道我的想法对不对。
      

  2.   

    insert into tableName values(....);select @@identity
      

  3.   

    先感谢上面几位的答复:但我试过了,使用executeUpdate("insert into tableName values(....);select @@identity "),返回的结果是1,我估计JAVA因为执行了前面的“insert”操作之后,返回了“影响1条记录”的结果。
    而后面的“select @@identity”,因为是要用executeQuery来执行的,所以没有执行到。如果用executeQuery("select @@identity")就可以返回标志列的编号了。
      

  4.   

    --@@IDENTITY和SCOPE_IDENTITY和IDENT_CURRENT的区别
    @@IDENTITY--是得到当前会话的所有范围的最后插入的IDENTITY值 
    SCOPE_IDENTITY--是得到当前会话的当前范围的最后插入的IDENTITY值 
    IDENT_CURRENT--是得到指定表的最后插入的IDENTITY值,与会话、范围无关。
      

  5.   

    好像SCOPE_IDENTITY比较合用,那么请问6楼,在JAVA中,这个SCOPE_IDENTITY是怎样用的呢?要用那个方法来调用呢?
      

  6.   

    锁表?还真是听都没有听过。
    请问是怎样用的?在JAVA中是用哪个方法来调用的?
      

  7.   

    select top 1 SCOPE_IDENTITY() from testtable
      

  8.   

    可能是你用的executeUpdate方法,本身就是返回受影响的行,而不是返回查询的结果
      

  9.   

    SCOPE_IDENTITY--是得到当前会话的当前范围的最后插入的IDENTITY值 
    范围小一些,这样就可以排除 insert后  触发器等操作产生新的ID
      

  10.   

    担心有理,一般情况 @@identity可以取出当前连接最后插入表的记录的标志值,但是会受触发器的影响
    select SCOPE_IDENTITY()则不受触发器影响
      

  11.   

    如果希望受当前会话,并且只取当前作用域的值的话那么使用scope_identity()函数。
      

  12.   

    回14楼,因为是在服务器端使用,所以当然是会有很多人在客户端进行输入操作的。否则就不会几个月就有17万多条数据了。
    不知道这样算不算是多线程。因为我其实还不懂多线程编程,只是懂得用数据库和JAVA的MVC结构,搭建一个简单的系统放在服务器,让员工用电脑输入资料而已。但对于服务器端来说,不知道这样是否就是多线程。另外,不知道你们说的“触发器”是不是MSSQL里面的触发器。我并没有编写触发器连接数据库来操作的,不知道是否会影响插入(insert)操作之后,立刻进行select @@identity操作返回的标志列编号的值。
      

  13.   


    你说的不是多线程,不同客户端不会影响 @@identity
    “触发器”是MSSQL里面的触发器,你不编写不代表以后会不会有人加上触发器,所以能注意救助以下好
      

  14.   

    使用scope_identity()不行啊!!!在查询管理器里面,放在insert语句后面就可以正常出现insert之后的标志列编号,但放在
    executeQuery(select scope_identity())里面的时候,就只能返回null。
    请问是不是用得不对?应该用哪个方法呢?
    因为用select @@indetity有可能出现不正确的标志列编号,我现在干脆用
    executeQuery(select max(sn) from tbl where 表中一个有unique约束的列=...)
    当然速度应该会慢了些。另外请问
    1、是否一个普通的列,搜索速度是否会比有索引的列要慢(我试过,慢好多,如果记录行数很多的话,但我还是想证实一下)?
    2、建立了UNIQUE之后,“约束”和“索引”有什么不一样?搜索速度是否“索引”要快些?
    3、“CLUSTERED”是否就是“聚集约束”?有什么用?我见到好像primary key都是CLUSTERED,如果是CLUSTERED是否搜索速度会快些?
    谢谢!
      

  15.   


    scope_identity() 返回当前会话,当前作用域最后标识值。你执行两次 executeQUERY,就是两个作用域了,当然取不到。如果你非要执行两次executeQuery,那只能用@@identity.  当然,如果insert时有触发器之类影响当前会话标识值的情况,就会取错。应该把insert和select scope_identity()放在一个批里executeQuery("insert ....;select scope_identity()");你说,insert时会产生一个空行集(因为它输出受影响的行数), 所以在java里取不到第二个结果集,那么有两种处理方式:1,ado里有 recordset.NextRecordset方法
    ado.net里 datareader有 nextResult方法
    odbc里也有类似的方法
    虽然我不懂java,也不太相信这么成熟的一个语言,没有提供类似的获取多个结果集的方法.2,语句里加上set nocount on
    executeQuery("set nocount on;insert....;select scope_identity();set nocount off");
      

  16.   

    1, 有索引的列搜索速度是否会比普通列快,要看索引是否能有效应用。
    2, unique约束是通过唯一索引实现的,也就是说unique约束就是一种唯一索引
    3, 是聚集索引. 没有聚集约束这种叫法吧。
      

  17.   

    回20楼:
    我没有用两个executeQuery啊?!我是用executeUpdate(insert into tbl values (.....)),然后用一个executeQuery(select ....)来取得编号。我试过用executeQuery(insert into tbl values (....);select scope_identity()),结果是出错!
      

  18.   

    我的意思是你执行两次,会不在同一作用域,因此scope_identity取不到值。
      

  19.   

    唉,搞掂了。原来我把代码改成
    executeQuery(insert into tbl values (....);select scope_identity())
    之后,没有存盘就执行了,结果还是象前面的那样报错了。存盘之后再运行,结果就正确了。
    非常感谢各位高手帮忙。谢谢!