PostgreSQL:在 PQexecPrepared() paramValues 参数中给出的类型与占位符和类型之间的关系

Posted

技术标签:

【中文标题】PostgreSQL:在 PQexecPrepared() paramValues 参数中给出的类型与占位符和类型之间的关系【英文标题】:PostgreSQL: relationship between types given w/placeholders and types in PQexecPrepared() paramValues parameter 【发布时间】:2019-01-18 15:04:57 【问题描述】:

如果我有一个作为$1::text 的占位符,这是否意味着我传递给PQexecPrepared() 的相应paramValues 需要是C 风格的字符串?到目前为止,我已经这样做了,到目前为止它已经奏效了。 (到目前为止,我需要将::text 与占位符一起提供,否则会出错)。但是如果我将占位符声明为$1:int 会怎样?我还能在paramValues 中给出一个 C 风格的字符串吗? 应该我给出一个 C 风格的字符串吗? docs on this 有点含糊,目前还不清楚使用PQprepare()paramTypes 参数做什么,我已经离开NULL

更重要的是,如果我需要表达一个数组,比如$1::text[],该怎么办?文档对此只字未提,到目前为止我看到的解决方案似乎不是很有效,甚至不是很可靠,例如https://***.com/a/36930781/1676382。到目前为止,我一直以“文本”格式将值提供给 PQexecPrepared(),但我应该切换到“二进制”吗?在什么条件下?

到目前为止,我已经能够摆脱一些非常简单的查询:

const char *query = "SELECT * FROM table WHERE col=$1::text";
const void *types = NULL;    //Wish I knew what could be assigned to an Oid
PQprepare(conn, name, query, 1, static_cast<const Oid *>(types));

...

const int *lengths = NULL;      //It doesn't seem like these vars are used for anything right now
const int *formats = NULL;
int result_format = 0;
//values is a const char * const * and is the return value of QScopedArrayPointer <char*>::data()
res = PQexecPrepared(conn, name, 1, values, lengths, formats, result_format);

到目前为止,这是可行的,但是如果我想拥有呢

WHERE col = ANY ($1::text[])

?我将如何表达传递给PQexecPrepared()values

我的项目是在 GNU C++ 中使用 PostgreSQL 9.6。

【问题讨论】:

这取决于:您是以文本格式还是二进制格式发送参数?您是否指定它们的类型?如果您在问题中添加代码示例,也许会有所帮助。 @LaurenzAlbe 问题表明我正在指定类型。到目前为止,我正在以“文本”格式进行操作,但问题的另一部分是我不知道我是否应该在什么条件下进行“二进制”操作。我将处理代码 sn-ps。 抱歉,我应该更具体一点:PQexecParamsparamTypesparamFormats 参数看起来如何? @LaurenzAlbe 我已经包含了 sn-ps,解释了我在做什么以及我想做什么(但简短的回答是这些参数是 NULL 【参考方案1】:

如果您像示例中那样发送无类型的字符串参数,它们将具有类型 unknown 并在可能的情况下转换为正确的类型。这与 SQL 语句中的字符串字面量非常相似。

在 SQL 语句中不必强制转换为 text。如果您认为有必要,我会很好奇 col 的类型是什么。

如果你想以文本格式传递text[],只需使用它的字符串表示,例如

first element,two,three

这也适用于整数和其他类型;只需使用值的文本表示。

您还可以使用PQexecParamsparamTypes 参数来明确指定它是哪种类型。可能的值在pg_typeoid 列中,对于系统类型它们是常量。

【讨论】:

我可以发誓::text 是必不可少的,但我不能重复我之前遇到的错误。无论如何,这比***.com/a/36930781/1676382 更好吗?似乎引擎仍然必须解析一个字符串,然后如果分隔符出现在其中一个值中,就会有危险 然后你必须用双引号转义条目,并在条目内用反斜杠转义双引号:entry one,entry two,"evil,\"entry" 我的职位很快就结束了,我的下一个根本不会涉及任何SQL,所以我没有机会真正测试它。我唯一的挑战是:您确定涵盖所有基础吗?我似乎记得调查过 PostgreSQL 转义并发现了一个可能不可靠的案例。 我很确定这是正确的,但我同意必须“手动”转义字符串并不好。

以上是关于PostgreSQL:在 PQexecPrepared() paramValues 参数中给出的类型与占位符和类型之间的关系的主要内容,如果未能解决你的问题,请参考以下文章

在 postgreSQL 9.2 上编辑 postgresql.conf 文件?

【PostgreSQL】在 Linux 下操作 PostgreSQL 的指令

如何解决这个问题 - 无法在 org.postgresql:postgresql:jar:42.2.4 收集依赖项

prometheus使用postgresql-adapter连接postgresql

PostgreSQL 函数和触发器在 postgresql 中包含更改

PostgreSQL概述