所以我在學校的一個專案中作業,現在我完全被卡住了。我只需要這一件事成功,我就可以了。
問題描述
我的問題是要獲得我在資料庫中插入的最后一件東西的id。
最低限度的例子
下載sqlite-jdbc-3.36.0.3,并將其放在當前作業目錄中。確保你沒有temp.sql檔案在里面(程式運行后將其洗掉)。
創建一個名為Main.java的檔案,內容如下:
import java.sql.Connection。
import java.sql.DriverManager。
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Main {
public static final String createDbQuery =
"CREATE TABLE temp (
"
"id integer PRIMARY KEY,
"
"data integer
"/span>
")"。
//在實際的代碼中,我使用了一個適當的PreparedStatement,但我將保留
//在這里是簡單的。
public static final String insertSomethingQuery =
"INSERT INTO temp (data) VALUES (340975)" 。
public static void main(String[] args){
Connection conn = null;
try {
conn = connect();
exec(createDbQuery, conn)。
exec(insertSomethingQuery, conn)。
/*
* 在這里嘗試一下將在其余部分提到的代碼
*問題
*/
} catch (final Exception e) {
e.printStackTrace()。
} finally {
if (conn != null) {
disconect(conn)。
}
}
}
public static Connection connect() throwsSQLException {
return DriverManager.getConnection("jdbc:sqlite:temp.sql") 。
}
public static void disconect(Connection conn) {
try {
conn.close()。
} catch (final SQLException e) {
e.printStackTrace()。
}
}
public static Statement exec(String query, Connection conn)
throws SQLException {
Statement s = conn.createStatement()。
s.execute(query)。
return s;
}
}
然后嘗試代碼:
- 編譯它。(
javac Main.java) - 移除
temp.sql,如果它存在的話 。
- 運行它。(
java -cp "./sqlite-jdbc-3.36.0.3.jar;。" Main)
如果有人在windows系統中使用powershell,我使用這個:
javac .Main.java; rm . emp.sql; java -cp ".sqlit-jdbc-3.36.0.3.jar;." Main
我嘗試了什么?
1)last_insert_rowid()
我在網上看到,last_insert_rowid()將回傳你在SQLite中最后插入的東西的id,所以我這樣做了:
final Integer id =
exec("SELECT last_insert_rowid()", conn).getUpdateCount()。
System.out.println("最后插入的id是"/span> id)。
然后我得到的結果是:
最后插入的id is -1
當我預期:
最后插入的id 是 1。
而且我知道預期的結果是正確的,因為如果我運行:
sqlite3.exe . emp.sql "SELECT * FROM temp"
輸出結果是:
1|340975
2) SELECT MAX(id) FROM ...
我知道最后插入的id永遠是表中最大的id(除非表的id是它能容納的最大值,但在我的應用程式中永遠不會出現這種情況,source),所以我試著這樣做:
2.
final Integer id =
exec("SELECT MAX(id) FROM temp"/span>, conn).getUpdateCount()。
System.out.println("最后插入的id是"/span> id)。
而我得到的輸出與使用last_insert_rowid()時相同。
然后嘗試用:
ResultSet rs =
exec("SELECT MAX(id) FROM temp"/span>, conn).getResultSet()。
if (! rs.next()) {
System.out.println("Something is wrong..."/span>)。
return;
}
final Integer id = rs.getInt("id")。
System.out.println("最后插入的id是" id)。
我得到:
java.sql.SQLException: no such column: 'id': 沒有這樣的列: 'id'findColumn(JDBC3ResultSet.java:49)
at org.sqlite.jdbc3.JDBC3ResultSet.getInt(JDBC3ResultSet.java:402)
at Main.main(Main.java:37)
uj5u.com熱心網友回復:
我已經有一段時間沒有使用sqlite了,但是我覺得這個看起來不對。
id = exec("SELECT last_insert_rowid()", conn).getUpdateCount();/code>
你沒有更新任何東西,所以不會有更新計數。
不應該是這樣的嗎?
ResultSet rs = conn. prepareStatement("select last_insert_rowid();").executeQuery()。
執行查詢是為了選擇,可以回傳一個結果集。它與用資料更新資料庫是不同的。
uj5u.com熱心網友回復:
函式last_insert_rowid()回報:
最后一行插入的ROWID,來自呼叫該函式的資料庫連接。
呼叫該函式的最后一行插入的ROWID
。
因此,如果你關閉了你進行最后一次插入的連接,并使用另一個連接運行查詢,你將不會得到最后插入的行的rowid。
另外,如果你的資料庫中有多個表,并且你用同一個連接在多個表中進行插入,你將不得不在每個表的最后一次插入后呼叫last_insert_rowid()以獲得每個表中最后插入的行的rowid。
當你在查詢中使用MAX(id),并且id被定義為INTEGER PRIMARY KEY時,你會得到表的最大id,而不一定是最后插入的行的rowid,因為:
如果你曾經洗掉過行,或者如果你曾經以最大的
可能的ROWID,那么以前洗掉的行的ROWID可能會在創建新的行時被重新使用。
在創建新行時可能會重復使用,并且新創建的ROWID可能不按嚴格的升序排列。
嚴格的升序。
確保MAX(id)將回傳最后插入的行的rowid的唯一方法是,如果您在定義id時也使用了關鍵字AUTOINCREMENT:
id INTEGER PRIMARY KEY AUTOINCREMENT
因為在這種情況下:
為新行選擇的ROWID至少要比
最大的ROWID,這個ROWID曾經存在于同一個表中。如果該
表之前從未包含過任何資料,那么就會使用1的ROWID。
最后,通常的做法是用它們的名字或別名來指代列,所以用:代替:SELECT MAX(id) FROM temp
你應該使用:
SELECT MAX(id) AS max_id from temp
這樣你就可以通過別名max_id來訪問查詢的結果:
final Integer id = rs. getInt("max_id")。
uj5u.com熱心網友回復:
所以在寫這個問題的時候,我找到了答案。但是現在我已經花了很大的力氣去寫了,我想我將會分享這個答案,并希望它對未來的人有幫助。
final Integer id =
exec("SELECT last_insert_rowid()"/span>, conn).getUpdateCount()。
System.out.println("最后插入的id是" id)。
是錯誤的,正確的做法是:
ResultSet rs =
exec("SELECT last_insert_rowid()", conn).getResultSet()。
if (! rs.next()) {
System.out.println("Something is wrong..."/span>)。
return;
}
final Integer id = rs.getInt("last_insert_rowid()") 。
System.out.println("最后插入的id是" id)。
而對于SELECT MAX ...的方式,正確的取值方式是:
ResultSet rs =
exec("SELECT MAX(id) FROM temp"/span>, conn).getResultSet()。
if (! rs.next()) {
System.out.println("Something is wrong..."/span>)。
return;
}
final Integer id = rs.getInt("MAX(id)")。
System.out.println("最后插入的id是" id)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/309805.html
標籤:
上一篇:我的問題是關于SQL中OR運算子的作業,它是否可以用來結合兩個選擇查詢?
下一篇:安卓SQL游標
