【问题标题】:How to use placeholders with "in (...)" clause?如何在(...)“条款中使用占位符?
【发布时间】:2014-01-05 22:23:50
【问题描述】:

我知道我可以通过插值来做到这一点。我可以使用占位符吗?

我收到此错误:

DBD::Pg::st execute failed: ERROR:  invalid input syntax for integer: "{"22,23"}" at ./testPlaceHolders-SO.pl line 20.

对于这个脚本:

#!/usr/bin/perl -w

use strict;
use DBI;

# Connect to database.

my $dbh = DBI->connect("dbi:Pg:dbname=somedb;host=localhost;port=5432", "somedb", "somedb");

my $typeStr = "22,23";
my @sqlParms = [ $typeStr ];
my $sqlStr = << "__SQL_END";
    SELECT id
    FROM states
    WHERE typeId in (?)
    ORDER BY id;
__SQL_END

my $query = $dbh->prepare($sqlStr);
$query->execute(@sqlParms);

my $id;
$query->bind_columns(\$id);

# Process rows

while ($query->fetch())
{
    print "Id: $id\n";
}

除了插值还有其他办法吗?

【问题讨论】:

  • 为什么要使用数组引用执行查询? [ $typeStr ]?
  • 是的,有办法绕过它。不要使用字符串,使用数字。如my @nums = (22,23); my $placeholder = join ",", ("?") x @nums; $query-&gt;execute(@nums);
  • 您的解决方案有效。如果你要正式回答,我会接受的。

标签: perl postgresql dbi


【解决方案1】:

DBD::PG 支持PostgreSQL arrays,因此您可以简单地编写如下查询:

WHERE typeid = ANY( ARRAY[1,2,3] )

或者,带有参数...

WHERE typeid = ANY(?)

那就只用数组支持

my @targets = (1,2,3);
# ...
$query->execute(\@targets);

【讨论】:

    【解决方案2】:

    根据要求发布评论作为答案。

    生成您自己的占位符字符串。像这样:

    my @nums = (22,23); 
    my $placeholder = join ",", ("?") x @nums; 
    $query->execute(@nums); 
    

    【讨论】:

    • 执行此操作时,请确保@nums 永远不会为空,因为in () 不幸会是一个sql 语法错误。
    • 在下面查看我的答案 - 有一种更简洁的方法。
    【解决方案3】:

    是的。您必须为每个值使用占位符,例如IN (?, ?, ?)。但是,您可以使用以下内容生成正确数量的问号(未经测试):

    my @values = (22, 23, ...);
    # will produce "?, ?, ..."
    my $in = join ", ", ("?") x @values;
    my $sqlStr = "SELECT id FROM states WHERE typeId in ($in) ORDER BY id;";
    my $query = $dbh->prepare($sqlStr);
    $query->execute(@values);
    

    请注意,如果您改用 DBIx::Class 之类的 ORM,则这种丑陋的 hack 会被抽象掉。

    【讨论】:

      【解决方案4】:

      您必须使用正确数量的问号构建 SQL 语句,然后设置参数值。无法将列表绑定到单个问号。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-31
        • 2018-10-13
        • 2014-05-21
        • 1970-01-01
        • 2022-11-07
        • 1970-01-01
        • 2020-12-25
        • 1970-01-01
        相关资源
        最近更新 更多