У меня есть следующие таблицы:
all_app_users
=============
all_app_user_id INT PRIMARY KEY NOT NULL
is_enabled BOOLEAN NOT NULL
myapp_users
===========
myapp_user_id INT PRIMARY KEY NOT NULL
all_app_user_id INT FOREIGN KEY (all_app_users)
myapp_user_stage INT NOT NULL
И следующий код JDBC:
Long allAppUserId = null;
Long myAppId = null;
Connection pooledConn = getPooledDBConnection();
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = pooledConn.prepareStatement("INSERT INTO all_app_users ( is_enabled ) VALUES ( ? )");
ps.setBoolean(1, true);
ps.execute();
ps.close();
ps = pooledConn.prepareStatement("SELECT IDENT_CURRENT('all_app_users')");
rs = ps.executeQuery();
allAppUserId = (long)rs.getInt(0);
rs.close();
ps = pooledConn.prepareStatement("INSERT INTO myapp_users ( all_app_user_id, myapp_user_stage ) VALUES( ?, ? )");
ps.setInt(1, Ints.checkedCast(allAppUserId));
ps.setInt(2, 5);
ps.execute();
ps.close();
ps = pooledConn.prepareStatement("SELECT IDENT_CURRENT('myapp_users')");
rs = ps.executeQuery();
myAppId = (long)rs.getInt(0);
pooledConn.commit();
System.out.println("Ping");
} catch(SQLException sqlExc) {
logger.error(ExceptionUtils.getStackTrace(sqlExc));
if(pooledConn != null) {
try {
pooledConn.rollback();
} catch (SQLException e) {
logger.error(ExceptionUtils.getStackTrace(e));
}
}
} finally {
try {
if(rs != null) {
rs.close();
}
if(ps != null) {
ps.close();
}
if(pooledConn != null) {
pooledConn.close();
}
} catch (SQLException e) {
logger.error(ExceptionUtils.getStackTrace(e));
}
}
System.out.println("Pong");
Когда я запускаю этот код, я не получаю никаких исключений, а сообщения "Ping" и "Pong" печатаются в STDOUT, однако myAppId
имеет значение NULL. Мне интересно, почему?
Возможно, это связано с моим использованием транзакций/коммитов? Должен ли я совершать после каждого из 4 последовательных операторов SQL? Я неправильно использую API JDBC?
В отличие от SCOPE_IDENTITY
, IDENT_CURRENT
не интересуется транзакциями или областью действия: он возвращает последний ключ идентификации, который был сгенерирован для таблицы.
IDENT_CURRENT
может возвращать NULL
если таблица не имеет столбца идентификатора, никогда не содержала строк или была усечена. Ничто из этого не применяется в вашей ситуации. Однако похоже, что вы неправильно выполняете скалярный запрос: вы никогда не вызываете rs.next()
перед вызовом rs.getInt(...)
:
ps = pooledConn.prepareStatement("SELECT IDENT_CURRENT('all_app_users')");
rs = ps.executeQuery();
rs.next(); // <<== Add this line
allAppUserId = (long)rs.getInt(0);
rs.close();
ps = pooledConn.prepareStatement("INSERT INTO myapp_users ( all_app_user_id, myapp_user_stage ) VALUES( ?, ? )");
ps.setInt(1, Ints.checkedCast(allAppUserId));
ps.setInt(2, 5);
ps.execute();
ps.close();
ps = pooledConn.prepareStatement("SELECT IDENT_CURRENT('myapp_users')");
rs = ps.executeQuery();
rs.next(); // <<== Add this line
myAppId = (long)rs.getInt(0);
rs.next()
. Есть идеи? Еще раз спасибо!SELECT IDENT_CURRENT('myapp_users')
в анализаторе запросов, верно?