如何将变量传递给带有 sqlx 的 do 块?

huangapple go评论79阅读模式
英文:

How to pass variable to a do block with sqlx?

问题

我正在尝试通过sqlx运行以下的do块脚本。由于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吗?

英文:

I am trying to run the following do block script in sql through sqlx. As do block doesn't accept parameters, I tried to prepare it beforehand.

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)
}

But as I run it, I got the following errors:

sql: expected 0 arguments, got 2

How can I fix this issue? Should I be using Preparex to replace prepare in sql?

答案1

得分: 4

"我应该使用Preparex来替换sql中的prepare吗?" -- 是的,然而你遇到的问题与Preparex或者Go语言本身无关。

DO命令的代码块是一个字符串字面量,这个字符串字面量在PREPARE命令执行期间不会被解析,也没有理由被解析,这就是为什么生成的预处理语句没有定义的参数。正如你正确指出的,DO不支持输入参数,但是试图通过将DO包装在一个预处理语句中来绕过这个限制只会产生你所希望的结果。

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

英文:

"Should I be using Preparex to replace prepare in sql?" -- Yes, however the problem you've encountered has nothing to do with Preparex, or the Go language itself, for that matter.

The code block of the DO command is a string literal, this string literal will not be, and has no reason to be, parsed during the PREPARE command execution, which is why the resulting prepared statement will have no defined parameters. As you correctly point out, DO does not support input parameters, but trying to get around that limitation by wrapping DO in a prepared statement will simply not produce the result you were hoping for.

If you need to conditionally execute parameterized SQL statements then you should use the CREATE FUNCTION command and explicitly execute the resulting function.

huangapple
  • 本文由 发表于 2021年7月13日 16:13:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/68358793.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定