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。 抱歉,我应该更具体一点:PQexecParams
的 paramTypes
和 paramFormats
参数看起来如何?
@LaurenzAlbe 我已经包含了 sn-ps,解释了我在做什么以及我想做什么(但简短的回答是这些参数是 NULL
)
【参考方案1】:
如果您像示例中那样发送无类型的字符串参数,它们将具有类型 unknown
并在可能的情况下转换为正确的类型。这与 SQL 语句中的字符串字面量非常相似。
在 SQL 语句中不必强制转换为 text
。如果您认为有必要,我会很好奇 col
的类型是什么。
如果你想以文本格式传递text[]
,只需使用它的字符串表示,例如
first element,two,three
这也适用于整数和其他类型;只需使用值的文本表示。
您还可以使用PQexecParams
的paramTypes
参数来明确指定它是哪种类型。可能的值在pg_type
的oid
列中,对于系统类型它们是常量。
【讨论】:
我可以发誓::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