Hasql:来自' SET'中变量替换的错误声明

时间:2017-01-30 16:28:39

标签: postgresql haskell hasql

我试图用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_idbigint / int8

以任一格式对$1值进行硬编码都有效。我尝试过不同的Hasql类型,例如E.textE.unknown这不起作用。

更新:使用execParams中更原始的postgresql-libpq函数。

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

不带引号的变量会产生FatalError结果。单引号变量会提供CommandOk,但对于以后的查询,类型(而不是bigint)是错误的。

1 个答案:

答案 0 :(得分:2)

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

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

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