Как передать переменную в блок do с помощью sqlx?

# #postgresql #go #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 = $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 для замены prepare в sql?

Ответ №1:

«Должен ли я использовать Preparex для замены prepare в sql?» — Да, однако проблема , с которой вы столкнулись, не имеет ничего общего ни с Preparex самим языком, ни Go с самим языком, если на то пошло.

Блок кода DO команды-это a string literal , этот строковый литерал не будет и не имеет оснований для анализа во PREPARE время выполнения команды, поэтому результирующий подготовленный оператор не будет иметь определенных параметров. Как вы правильно заметили, DO не поддерживает входные параметры, но попытка обойти это ограничение путем обертывания DO в подготовленный оператор просто не приведет к результату, на который вы надеялись.

Если вам нужно условно выполнить параметризованные инструкции SQL, то вы должны использовать CREATE FUNCTION команду и явно выполнить полученную функцию.