我正在努力为Postgres正确利用sqlx
和pq
驱动程序来在数据库中创建一行。让我们开始简单:
我有一个user
,role
和user_role
表。我想在数据库中插入一个角色并获取插入行的ID。使用以下sql可以完美地工作:
const createRoleSQL = "INSERT INTO role (name) VALUES (:name) RETURNING id"
为使工作顺利进行,我在某个时候准备声明:
createStmt, err := db.PrepareNamed(createRoleSQL)
if err != nil {
// ...
}
创建时,我将查询作为事务tx
的一部分运行。 role
显然是具有正确字段和db
标签的结构:
if err := tx.NamedStmt(createStmt).QueryRow(role).Scan(&role.ID); err != nil {
// ...
}
这很好用。
现在我想扩展它并插入一个新角色并将其分配给用户:
const createUserRoleSQL = `
DO $$
DECLARE role_id role.id%TYPE;
BEGIN
INSERT INTO role (name) VALUES ($2) RETURNING id INTO role_id;
INSERT INTO user_role (user_id, role_id) VALUES ($1, role_id);
END $$`
createStmt, err := db.Preparex(createUserRoleSQL)
if err != nil {
// ...
}
if err := tx.Stmtx(createStmt).QueryRow(userID, role.Name).Scan(&role.ID); err != nil {
// ...
}
不幸的是,此操作失败,出现sql: expected 0 arguments, got 2
。只需一个查询就能实现我想做的事吗?