我正在尝试使用 Hasql 编写一个参数化语句来在 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"
上述结果为:
ResultError (ServerError "42601" "syntax error at or near "$1"" Nothing Nothing)
添加单引号,例如
sql = "set my_session.organization_id = '$1'"
当我使用变量运行查询时给出以下结果:
ResultError (ServerError "22P02" "invalid input syntax for integer: "$1"" Nothing Nothing)
这确实有意义,因为organization_id
是bigint
/int8
。
任一格式对$1
值进行硬编码都有效。我尝试过不同的 Hasql 类型,例如 E.text
和E.unknown
,这是行不通的。
更新:使用postgresql-libpq
中更原始的execParams
函数。
execParams c "SET my_session.organization_id = '$1'" [Just (Oid 20, "1",Text)] Text
不带引号的变量给出FatalError
结果。单引号变量给出CommandOk
,但对于以后的查询是错误的类型(不是bigint
)。
SET
命令不能与预准备语句一起使用。这是PostgreSQL的一个限制。预准备语句是具有可选参数的语句,可以使用不同的参数值多次执行。所有带有参数的语句都是 PostgreSQL 中的预准备语句,无论您是否只执行它们一次,或者是否为它们命名以供重用。
您必须使用常量值构造一个查询字符串并执行该字符串。
或者,您可以在 PostgreSQL 中编写一个函数,该函数使用动态 SQL 为您运行 set 命令,并在带有参数的准备好的 SELECT
语句中调用该函数。