首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DBD::Pg::st execute failed: ERROR:语法错误位于或接近"$1“

DBD::Pg::st execute failed: ERROR:语法错误位于或接近"$1“
EN

Stack Overflow用户
提问于 2013-05-24 09:45:45
回答 1查看 2.9K关注 0票数 5

尝试使用Perl和DBI在PostgreSQL中设置值,从而设置DBD::Pg。

我收到一个奇怪的错误。

代码语言:javascript
复制
2013-05-23 19:02:36.641139500 updating status to 0
2013-05-23 19:02:36.641410500 DBD::Pg::st execute failed: ERROR:  syntax error at or near "$1"
2013-05-23 19:02:36.641418500 LINE 1: UPDATE instances SET $1 = $2
2013-05-23 19:02:36.641423500                              ^ at /usr/lib/perl5/vendor_perl/Mitel/MslRest/mbg.pm line 161.
2013-05-23 19:02:36.642425500 [Thu May 23 19:02:36 2013] [error] DBD::Pg::st execute failed: ERROR:  syntax error at or near "$1"
2013-05-23 19:02:36.642438500 LINE 1: UPDATE instances SET $1 = $2
2013-05-23 19:02:36.642443500                              ^ at /usr/lib/perl5/vendor_perl/Mitel/MslRest/mbg.pm line 161.
2013-05-23 19:02:36.642447500

相关代码为

代码语言:javascript
复制
my $sql = "UPDATE instances SET ? = ?";
my $dbh = Mitel::tug::getdbh();
$dbh->begin_work;
my $sth = $dbh->prepare($sql);
unless ($sth) {
    return $self->internal_error("prepare failed: " . $dbh->errstr);
}
foreach my $propname (sort keys %{ $raw_data }) {
    my $propval = $raw_data->{$propname};
    print STDERR "updating $propname to $propval\n";
    if (! $sth->execute($propname, $propval)) {
        $dbh->rollback;
        $sth->finish;
        return $self->internal_error("execute: " . $dbh->errstr);
    }
}
$dbh->commit;
$sth->finish;

因此,我试图使用execute方法将"status“更新为0,以防止sql注入,但由于某种原因,我得到了一个语法错误。

有没有人碰到这个?

代码语言:javascript
复制
root@miketug2 ~]# perl -v

This is perl, v5.10.1 (*) built for i386-linux-thread-multi

perl-DBD-Pg-2.15.1-4.el6_3.i686
postgresql84-server-8.4.14-1PGDG.rhel6.i686

root@miketug2 ~]# uname -a
Linux miketug2 2.6.32-279.22.1.el6.i686 #1 SMP Wed Feb 6 00:31:03 UTC 2013 i686 i686 i386 GNU/Linux
EN

回答 1

Stack Overflow用户

发布于 2013-05-24 10:20:13

PostgreSQL更喜欢使用数字占位符($1$2,...)因此有人将您的?占位符转换为数字占位符;这就是为什么您的?

代码语言:javascript
复制
UPDATE instances SET ? = ?

最终结果为:

代码语言:javascript
复制
UPDATE instances SET $1 = $2

在错误消息中。

现在真正的问题是,您不能使用占位符作为标识符(表名、列名等),您只能将占位符用于值。您不能说SET ? = ?,您必须以其他方式提供列名,可能是通过字符串插值。这意味着你必须将你的prepare移到你的循环中,如下所示:

代码语言:javascript
复制
foreach my $propname (sort keys %{ $raw_data }) {
    my $prop    = $dbh->quote_identifier($propname);
    my $propval = $raw_data->{$propname};
    my $sth     = $dbh->prepare("UPDATE instances SET $prop = ?");
    $sth->execute($propval);
    $sth->finish();
}

当然,您的实际代码将包含错误处理。请注意,使用quote_identifier使列名可以安全地进行插值。如果你打算使用这个简单的prepareexecutefinish序列,那么你可能只想使用do

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16726515

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档