可以在 DBI 的 selectcol_arrayref & 中使用命名占位符公司?

发布于 2024-12-22 13:50:17 字数 376 浏览 1 评论 0 原文

在 DBI 允许 @bind_values 的情况下是否可以使用命名占位符?例如,我想做这样的陈述:

my $s = $DB->selectcol_arrayref ("SELECT a FROM b
                                  WHERE c = ? OR d = ? OR e = ?;",
                                  {},
                                  $par1, $par2, $par1) or
        die ($DB->errstr ());

不太容易出错。我正在使用 DBD::Pg 和 DBD::SQLite。

Is it somehow possible to use named placeholders where DBI allows @bind_values? E. g., I would like to make statements like:

my $s = $DB->selectcol_arrayref ("SELECT a FROM b
                                  WHERE c = ? OR d = ? OR e = ?;",
                                  {},
                                  $par1, $par2, $par1) or
        die ($DB->errstr ());

less prone to mistakes. I'm using DBD::Pg and DBD::SQLite.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

煮酒 2024-12-29 13:50:17

支持什么类型的占位符(如果有)取决于司机:

占位符和绑定值

某些驱动程序支持占位符和绑定值。
[...]
某些驱动程序还允许使用 :name:N 等占位符(例如 :1:2 等on) 除了?,但它们的使用不可移植。

但你很幸运,PostgreSQL 驱动程序 支持命名或编号参数:

DBD::Pg 中可以使用三种类型的占位符。第一种是“问号”类型,其中每个占位符都由单个问号字符表示。
[...]
该方法的第二种类型的占位符是“美元符号数字”。
[...]
最终占位符类型是“命名参数”,格式为“:foo”。

SQLite 驱动程序也支持它们:

SQLite 支持多种占位符表达式,包括 ?和:AAAA。

缺点是您最终将大量使用 bind_param 和命名参数,因此您将无法使用 selectcol_arrayref$sth 等便利工具>execute(1,2,3)注意:如果有人知道如何在 execute 中使用命名占位符,我会很感激评论中的一些指示,我从来没有弄清楚如何去做)。但是,您可以使用各种形式的数字占位符(例如对于 PostgreSQL 为 select c from t where x = $1 或对于 SQLite 为 select c from t where x = ?1 )。

另请注意,PostgreSQL 使用冒号表示数组切片,使用问号表示某些运算符,因此有时标准 ? 占位符和 :name 命名占位符可能会导致问题。我从来没有遇到过任何问题 ? 但我从未使用过 几何运算符 之一;我怀疑合理使用空格可以避免 ? 的任何问题。如果您不使用 PostgreSQL 数组,那么您可能不必担心 数组切片与您的 :name 命名占位符发生冲突。


执行摘要:您不能将命名占位符与 selectcol_arrayref 或与 @bind_params 配合使用的类似方法一起使用。但是,对于 SQLite 和 Postgresql,您可以使用编号占位符($1$2、... 对于 Postgresql 或 ?1 ?2, ... 对于 SQLite),使用与 @bind_params 配合使用的方法,或者您可以使用命名占位符(:name 对于 PostgreSQL 和 SQLite)如果您愿意使用更长的时间prepare/bind_param/execute/fetch 方法序列,如果您使用 PostgreSQL,则必须小心查询中的数组。

What sorts of placeholders (if any) are supported depends on the driver:

Placeholders and Bind Values

Some drivers support placeholders and bind values.
[...]
Some drivers also allow placeholders like :name and :N (e.g., :1, :2, and so on) in addition to ?, but their use is not portable.

But you're in luck, the PostgreSQL driver supports named or numbered parameters:

There are three types of placeholders that can be used in DBD::Pg. The first is the "question mark" type, in which each placeholder is represented by a single question mark character.
[...]
The method second type of placeholder is "dollar sign numbers".
[...]
The final placeholder type is "named parameters" in the format ":foo".

And the SQLite driver also supports them:

SQLite supports several placeholder expressions, including ? and :AAAA.

The downside is that you'll end up using bind_param a lot with the named parameters so you won't be able to use conveniences like selectcol_arrayref and $sth->execute(1,2,3) (Note: If anyone knows how to use named placeholders with execute I'd appreciate some pointers in a comment, I've never figured out how to do it). However, you can use the various forms of number placeholders (such as select c from t where x = $1 for PostgreSQL or select c from t where x = ?1 for SQLite).

Also be aware that PostgreSQL uses colons for array slices and question marks for some operators so sometimes the standard ? placeholders and :name named placeholders can cause problems. I've never had any problems with ? but I've never used the geometric operators either; I suspect that sensible use of whitespace would avoid any problems with ?. If you're not using PostgreSQL arrays, then you probably don't have to worry about array slices fighting with your :name named placeholders.


Executive Summary: You can't use named placeholders with selectcol_arrayref or similar methods that work with @bind_params. However, with SQLite and Postgresql, you can use numbered placeholders ($1, $2, ... for Postgresql or ?1, ?2, ... for SQLite) with the methods that work with @bind_params or you can use named placeholders (:name for both PostgreSQL and SQLite) if you're happy using the longer prepare/bind_param/execute/fetch sequence of methods and you'll have to be careful if you use PostgreSQL arrays in your queries.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文