我试图将新行插入到 sqlite 表中并返回其 id,或返回现有行的 id,但我无法让这两种情况都工作。我正在使用 golang 和 mattn/sqlite3。根据我读到的内容,执行此操作的方法将是这样的:
var userid int64
row := s.db.QueryRow(`
INSERT OR IGNORE INTO users (email) VALUES (?);
SELECT id FROM users WHERE email = ?;`,
email, email)
err := row.Scan(&userid)
但是,如果该行不存在,则此操作会失败并出现“无行”错误,并且不会插入该行,就好像第一个语句被简单地忽略一样。如果我将它压缩成一个带有返回子句的语句,如下所示:
var userid int64
row := s.db.QueryRow(`
INSERT OR IGNORE INTO users (email) VALUES (?)
RETURNING id;`,
email)
err := row.Scan(&userid)
然后在该行已经存在的情况下会失败,因为“忽略”也会跳过返回子句。
我不明白为什么第一个版本失败了。 golang的sql接口不能执行带返回值的多语句查询吗?我找不到任何关于此的文档。还是我做错了什么?
您可以使用UPSERT语句。
create table users (id int primary key,email varchar(100) unique );
insert into users values
(1,'[email protected]')
,(2,'[email protected]')
;
首先插入
insert into users values
(3,'[email protected]')
on conflict(email) do update set email=excluded.email
returning id
退货
id |
---|
3 |
下一个插入
insert into users values
(3,'[email protected]')
on conflict(email) do update set email=excluded.email
returning id
id |
---|
3 |