【问题标题】:PostgreSQL syntax error in parameterized query on "date $1"“日期 $1”的参数化查询中的 PostgreSQL 语法错误
【发布时间】:2015-08-18 12:49:37
【问题描述】:

尝试参数化我的 SQL 查询(使用 libpq 函数 PQexecParams),我遇到了语法错误:

SELECT date $1

错误是:

ERROR:  syntax error at or near "$1"

【问题讨论】:

  • @ErwinBrandstetter 我使用的是 PQexecParams,但要点是一样的。我试图解决您的 cmets,但请随时编辑问题。
  • 您的更新澄清了一些事情。有趣的问题。

标签: postgresql types prepared-statement parameter-passing libpq


【解决方案1】:

Prepared statements

对此的解释可以在in the chapter Constants of Other Types of the manual找到:

::CAST() 和函数调用语法也可用于指定 任意表达式的运行时类型转换,如在 Section 4.2.9为避免语法歧义,type 'string' 语法 只能用于指定简单文字常量的类型。 'string' syntax 类型的另一个限制是它不 适用于数组类型;使用::CAST() 指定数组的类型 常数。

我的大胆强调。

prepared statements 的参数实际上不是 sting literals 而是类型化的 values,因此您不能使用 type 'string' 形式。使用其他两种形式之一将值转换为不同的类型,就像您已经发现的那样。

例子:

PREPARE foo AS SELECT $1::date;

EXECUTE foo('2005-1-1');

PQexecParams in the libpq C library 类似

文档:

... 在 SQL 命令文本中,将显式强制转换附加到参数 符号以显示您将发送的数据类型。例如:

SELECT * FROM mytable WHERE x = $1::bigint;

这会强制将参数$1 视为bigint,而默认情况下 它将被分配与 x 相同的类型。强制参数类型 以这种方式或通过指定数字类型 OID 的决定是 强力推荐。 ...

替代方法,如上面引用中所述,是使用paramTypes[] 传递各个数据类型的 OID - 如果您确实需要转换。在大多数情况下,让 Postgres 从查询上下文中派生数据类型应该可以正常工作。

paramTypes[]

通过 OID 指定要分配给参数的数据类型 符号。如果paramTypesNULL,或者数组中的任何特定元素 为零,服务器推断参数符号的数据类型 与无类型文字字符串相同。

可以从系统目录pg_type获取数据类型的OID:

SELECT oid FROM pg_type WHERE typname = 'date';

您必须使用正确的内部类型名称。例如:int4 代表 integer
或者使用方便的转换为regtype

SELECT 'date'::regtype::oid;

这更灵活,因为类型名称的已知别名也被接受。例如:int4intinteger 代表 integer

【讨论】:

    【解决方案2】:

    解决方案是使用类型转换而不是date

    SELECT $1::date
    

    【讨论】:

    • 我花了相当多的时间来弄清楚这一点 :-)
    • 不过,答案很有趣。
    • 您如何以及在何处使用此语句?如果“按原样”运行,这仍然是无效的 SQL
    猜你喜欢
    • 1970-01-01
    • 2014-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-21
    • 1970-01-01
    相关资源
    最近更新 更多