0

I'm trying to write a parameterized statement with Hasql to set a variable in PostgreSQL.

import qualified Hasql.Encoders as E
import qualified Hasql.Decoders as D

setOrganization :: Query Int64 ()
setOrganization = statement sql (E.value E.int8) D.unit False
  where
    sql = "set my_session.organization_id = $1"

The result from the above is:

ResultError (ServerError "42601" "syntax error at or near \"$1\"" Nothing Nothing)

Adding single quotes e.g.

    sql = "set my_session.organization_id = '$1'"

Gives this result when I run a query using the variable:

ResultError (ServerError "22P02" "invalid input syntax for integer: \"$1\"" Nothing Nothing)

Which does make sense since the organization_id is a bigint / int8.

Hard-coding the $1 value in either format works. I've tried different Hasql types e.g. E.text and E.unknown and that does not work.


Update: Using the more primitive execParams function from postgresql-libpq.

execParams c "SET my_session.organization_id = '$1'" [Just (Oid 20, "1",Text)] Text

Unquoted variable gives FatalError result. Single-quoted variable gives CommandOk, but is wrong type (not bigint) for later queries.

4

1 回答 1

2

SET命令不能与准备好的语句一起使用。这是 PostgreSQL 的限制。准备好的语句是带有可选参数的语句,可以使用不同的参数值执行多次。在 PostgreSQL 中,所有带参数的语句都是准备好的语句,无论您是只执行一次还是给它们一个名称以供重用。

您必须构造一个具有常量值的查询字符串并执行它。

或者,您可以在 PostgreSQL 中编写一个函数,使用动态 SQL 为您运行 set 命令,并在SELECT带有参数的准备好的语句中调用该函数。

于 2017-01-30T16:36:05.567 回答