我正在使用SQLite。我有两张桌子:
Log:
pid INTEGER PRIMARY KEY AUTOINCREMENT
action INTEGER NOT NULL
.... ect.
ErrorExtras:
pid INTEGER REFERENCES log(pid)
msg TEXT,
request TEXT
现在发生错误时,我想插入两者。插入Log很容易,因为它会生成PID,但是,插入ErrorExtras更难,因为我不知道PID而不进行查询。如果我插入Log,查询PID然后插入ErrorExtras,这似乎很麻烦。这些插入是否有某种捷径?
在我的情况下,这是可能的,因为日志中的其他信息唯一地标识了pid(所以有一个组合键),但如果不是这样的话呢?
答案 0 :(得分:1)
您无需查询insert_id,只需在ErrorExtras
中的select语句中使用last_insert_id,而将Bob作为您的叔叔。
答案 1 :(得分:1)
如果您可以控制SQL命令,则可以使用last_insert_rowid
SQL function,如下所示:
INSERT INTO Log(action) VALUES(42);
INSERT INTO ErrorExtras(pid, msg) VALUES(last_insert_rowid(), 'x');
(但这仅适用于下一个INSERT
命令,因为之后,last_insert_rowid()
会返回rowid
记录的ErrorExtras
。)
如果您使用的是C API,则可以使用sqlite3_last_insert_rowid
function:
sqlite3_prepare_v2(db, "INSERT INTO Log(action) VALUES(42)", -1, &stmt, NULL);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
sqlite3_prepare_v2(db, "INSERT INTO ErrorExtras(pid,msg) VALUES(?,?)", -1, &stmt, NULL);
sqlite3_bind_int64(stmt, 1, sqlite3_last_insert_rowid(db));
sqlite3_bind_text(stmt, 2, "x", -1, SQLITE_TRANSIENT);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
其他语言的API通常也有一些机制来获取最后插入的rowid
。
例如,在Android中,insert
函数返回它:
ContentValues cv = new ContentValues();
cv.put("action", 42);
long log_rowid = db.insert("Log", null, cv);
ContentValues cv = new ContentValues();
cv.put("pid", log_rowid);
cv.put("msg", "x");
db.insert("ErrorExtras", null, cv);