我试图用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
这不起作用。
更新:使用execParams
中更原始的postgresql-libpq
函数。
execParams c "SET my_session.organization_id = '$1'" [Just (Oid 20, "1",Text)] Text
不带引号的变量会产生FatalError
结果。单引号变量会提供CommandOk
,但对于以后的查询,类型(而不是bigint
)是错误的。
答案 0 :(得分:2)
SET
命令不能与预准备语句一起使用。这是PostgreSQL的限制。 预处理语句是一个带有可选参数的语句,可以使用不同的参数值执行多次。所有带参数的语句都是PostgreSQL中的预处理语句,无论你只执行一次还是给它们一个名称进行重用。
您必须构造一个具有常量值的查询字符串并执行该字符串。
或者,您可以在PostgreSQL中编写一个函数,该函数使用动态SQL为您运行set命令,并在带有参数的准备好的SELECT
语句中调用该函数。