1 回答

TA贡献1886条经验 获得超2个赞
pq.CopyIn内部使用 COPY FROM,它不支持该子句。ON CONFLICT
但是,您可以做的是创建一个没有约束的临时表,将数据复制到该临时表中,然后使用您的子句在目标表中执行 操作,使用临时表作为要插入的数据源。INSERTON CONFLICT
一个例子应该更清楚地说明这一点,假设你有一个看起来像这样的表:users
CREATE TABLE users (
id serial PRIMARY KEY
, name text
, email text UNIQUE
);
假设你有一部分用户像这样:
var users = []User{
{Name: "John Doe", Email: "jdoe@example.com"},
{Name: "Joe Blow", Email: "jblow@example.com"},
{Name: "Jane Doe", Email: "jdoe@example.com"}, // duplicate email!
{Name: "Foo Bar", Email: "fbar@example.com"},
}
这样,您可以执行以下操作:
_, err = txn.Exec(`
CREATE TEMP TABLE users_temp
ON COMMIT DROP
AS SELECT * FROM users
WITH NO DATA`)
if err != nil {
panic(err)
}
stmt, err := txn.Prepare(pq.CopyIn("users_temp", "name", "email"))
if err != nil {
panic(err)
}
for _, u := range users {
if _, err := stmt.Exec(u.Name, u.Email); err != nil {
panic(err)
}
}
if _, err := stmt.Exec(); err != nil {
panic(err)
}
if err := stmt.Close(); err != nil {
panic(err)
}
_, err = txn.Exec(`
INSERT INTO users (name, email)
SELECT name, email FROM users_temp
ON CONFLICT DO NOTHING`)
if err != nil {
panic(err)
}
if err := txn.Commit(); err != nil {
panic(err)
}
运行上述操作后,您可以这样做,您将获得以下内容:SELECT * FROM users;
id | name | email
----+----------+-------------------
1 | John Doe | jdoe@example.com
2 | Joe Blow | jblow@example.com
4 | Foo Bar | fbar@example.com
(3 rows)
对于特定的示例和要求,您可以在查询中执行如下操作:INSERT ... SELECT ...
_, err = txn.Exec(`
INSERT INTO test (unique_token, frequency)
SELECT unique_token, COUNT(*) FROM token_temp
GROUP BY unique_token`)
if err != nil {
panic(err)
}
- 1 回答
- 0 关注
- 120 浏览
添加回答
举报