Sqlite - 使用自动递增PID插入多个表

时间:2013-01-09 00:50:11

标签: sqlite

我正在使用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(所以有一个组合键),但如果不是这样的话呢?

2 个答案:

答案 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);