0

我正在使用 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(所以有一个组合键),但如果不是这种情况怎么办?

4

2 回答 2

1

You needn't query for the insert_id, just use the last_insert_id in the select statement in ErrorExtras and Bob's your uncle.

于 2013-01-09T00:56:15.783 回答
1

如果您可以控制 SQL 命令,则可以像这样使用last_insert_rowidSQL 函数

INSERT INTO Log(action) VALUES(42);
INSERT INTO ErrorExtras(pid, msg) VALUES(last_insert_rowid(), 'x');

(但这仅适用于下一个INSERT命令,因为之后last_insert_rowid()返回记录rowidErrorExtras。)


如果您使用的是 C API,则可以使用以下sqlite3_last_insert_rowid函数

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);
于 2013-01-09T09:08:05.327 回答