如何使用 go 和 sqlite 在单个查询中插入或忽略一行并返回其 id?

问题描述 投票:0回答:1

我试图将新行插入到 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接口不能执行带返回值的多语句查询吗?我找不到任何关于此的文档。还是我做错了什么?

sql sqlite go
1个回答
0
投票

您可以使用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
© www.soinside.com 2019 - 2024. All rights reserved.