如何使用 sqlx 将变量传递给 do 块?

How to pass variable to a do block with sqlx?

我正在尝试 运行 do 在 sql 至 sqlx 中阻止脚本。由于do块不接受参数,我试着提前准备好。

func LinkSessionUser(sessionId string, userId string, result *bool) error  {
    db := database.GetDB()
    statement, err := db.Preparex(`
        do
        $$
        begin
        if (exists(select id from "session" where id = ) and exists(select id from "user" where id = )) then
          return insert into "session_user" (session_id, user_id) values (, ) on conflict do nothing;
        else
          raise exception "Either session(id=%) or user(id=%) doesn't exist" , ;
        end if;
        end
        $$;
    `)
    if err != nil {
        return err
    }
    return statement.Get(result, sessionId, userId)
}

但是当我 运行 它时,我得到了以下错误:

sql: expected 0 arguments, got 2

我该如何解决这个问题?我应该使用 Preparex 来替换 sql 中的 prepare 吗?

"我应该使用 Preparex 代替 sql 中的 prepare 吗?" -- 是的,但是您遇到的问题与 Preparex,或 Go 语言本身,就此而言。

DO 命令的 code 块是一个 string literal,这个字符串文字不会,也没有理由,在PREPARE 命令执行,这就是为什么生成的准备语句将 没有 定义的参数。正如您正确指出的那样,DO 不支持输入参数,但是试图通过将 DO 包装在准备好的语句中来绕过该限制将根本不会产生您希望的结果。

如果你需要有条件地执行参数化SQL语句那么你应该使用CREATE FUNCTION命令并显式执行结果函数。