日期:2014-05-18  浏览次数:20771 次

SELECT @@IDENTITY 时而返回 0,急求解决办法(100分)
public   static   int   executeCreateandReturnID(String   SQL,String   poolName)   {
        if   (SQL   ==   null   ||   SQL.length()   ==   0)   {
            return   0;
        }
        int   i   =   0,   nCreateId   =   0;
        Connection   conn   =   DBService.getConn(poolName);
        try   {
//             System.out.println(SQL);
         
            Statement   stmt   =   conn.createStatement();
            i   =   stmt.executeUpdate(SQL);
            if   (i   >   0)   {
                //Get   IDENTITY   id
                ResultSet   rs   =   stmt.executeQuery( "SELECT   @@IDENTITY ");
                if   (rs.next())   {
                    nCreateId   =   rs.getInt(1);
                }
                rs.close();
            }
            stmt.close();
        }   catch   (Exception   e)   {
            e.printStackTrace();
        }   finally   {
            DBService.closeConn(poolName,conn);
        }
        return   nCreateId;
    }


现在我程序偶尔会发生执行这段代码后,返回的ID值是0,而实际insert语句是执行成功的。代码如上,请各位老大帮忙看看,哪里出了问题?怀疑的重点是连接池中其他会话的并发引起的

怎么解决?最好能说明原因。

这个系统再我们这边测试的时候都没有问题,但是在用户那边用上去不久经常发现数据错乱,用户那边催的很急啊,请各位大侠相助啊。

问题解决立马送分

------解决方案--------------------
@@IDENTITY 用 SCOPE_IDENTITY() 替换试试。
------解决方案--------------------
stmt.executeUpdate(SQL);
既然是想返回值那么LZ的写法有点多余了

这样的写法就很好了,没有必要去判断更新所影响的行数,然后决定是否去取identity的值

把两句话放在一起执行可以保证返回的IDENTITY值绝对正确,
而且如果返回的IDENTITY值0那么肯定是执行失败了,程式中少做了很多无用功


Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(SQL + ";SELECT @@IDENTITY ");
if (rs.next()) {
nCreateId = rs.getInt(1);
}
rs.close();

或者在传入SQL这个参数之前就在后面加上+ ";SELECT @@IDENTITY "


另外建议用SCOPE_IDENTITY()替代@@IDENTITY,因为@@IDENTITY是全局变量,而SCOPE_IDENTITY()的作用域只限于当前连接,虽然这样的替换不是必要,但是相信LZ应该很清楚使用全局变量和局部变量那个更好