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

问题描述

我正在尝试通过 dosql 中运行以下 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 = $1) and exists(select id from "user" where id = $2)) then
          return insert into "session_user" (session_id,user_id) values ($1,$2) on conflict do nothing;
        else
          raise exception "Either session(id=%) or user(id=%) doesn't exist" $1,$2;
        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 或 {{1 }} 语言本身,就此而言。

Go 命令的 code 块是一个 DO,在 {{1} } 命令执行,这就是结果准备好的语句将没有定义参数的原因。正如您正确指出的那样,string literal 不支持输入参数,但试图通过将 PREPARE 包装在准备好的语句中来绕过该限制根本不会产生您希望的结果。

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