首页 > 解决方案 > 按引用或按值扫描函数

问题描述

我有以下代码:

statement := `SELECT id from source where mgmt = $1 `
var exists string
errUnique := dr.db.QueryRow(statement, mgmt).Scan(exists)
if errUnique != nil && errUnique != sql.ErrNoRows {
    return errUnique
}

上面的代码对我有用。但是,我不应该 .Scan(&exists)有一个引用吗?这不起作用。另一方面,当我将存在更改为这里看到的布尔值时,var exists bool突然.Scan(&exists)起作用了。为什么字符串不起作用exists并且.Scan(&exists)不起作用?

标签: go

解决方案


您应该具有exists与您从数据库中检索的值的类型相同或兼容的类型。

由于您正在选择该id列,我将假设它是一个integer,因此您应该如下声明存在var exists int。但是,如果您想查明表中是否存在某行,您通常会使用以下形式的查询:

SELECT EXISTS(SELECT 1 FROM source WHERE mgmt= $1)

(至少在 postgres 中,我不确定您使用的是什么数据库)

EXISTS

EXISTS 的参数是任意的 SELECT 语句或子查询。评估子查询以确定它是否返回任何行。如果返回至少一行,则 EXISTS 的结果为“真”;如果子查询没有返回任何行,则 EXISTS 的结果为“false”。

然后你的 Go 代码会是这样的:

query := `SELECT EXISTS(SELECT 1 FROM source WHERE mgmt = $1)`

var exists bool
if err := dr.db.QueryRow(query, mgmt).Scan(&exists); err != nil {
    return err
}

if exists {
    // already taken
} else {
    // unique
}

另请注意,由于EXISTS始终返回布尔值,因此您不必检查错误sql.ErrNoRows,如果确实收到错误,则不会是那个错误。


推荐阅读