【问题标题】:How can I insert into PostgreSQL using Perl, DBI and placeholders?如何使用 Perl、DBI 和占位符插入 PostgreSQL?
【发布时间】:2012-12-22 03:55:00
【问题描述】:

我正在尝试在 pSQL 表中插入一行,同时指定键和值作为占位符:

my @keys = keys %db_entr;                                                            
my @vals = values %db_entr;

my @items = (@keys, @values);

my $dbh = DBI->connect("DBI:Pg:dbname=testdb;host=localhost", "username", 'password', {'RaiseError' => 1});                                                                   
my $sth = $dbh->prepare("INSERT INTO grid ( ?, ?, ? ) values ( ?, ?, ? )");
my $rows = $sth->execute(@items);                                                    
print "$rows effected\n";

但是,无论我做什么,这都会给我一个错误:

DBD::Pg::st execute failed: ERROR:  syntax error at or near "$1"
LINE 1: INSERT INTO grid ( $1, $2, ...
                           ^ at ./file.pl line 262, <STDIN> line 11.

有人知道我可能做错了什么吗?

【问题讨论】:

  • 您的代码示例没有意义,您没有显示@items 的创建位置

标签: perl postgresql dbi


【解决方案1】:

您不能对这样的列名使用占位符:

INSERT INTO grid (?, ?, ?) VALUES (?, ?, ?)

您必须明确指定列名,并且只能对值使用占位符:

INSERT INTO grid (x, y, z) VALUES (?, ?, ?)

【讨论】:

    【解决方案2】:

    您不能在prepare 调用中为列名使用占位符。您可以做的最好的事情是将变量名插入到 SQL 字符串中,或​​者使用sprintf 进行等效操作。

    这是一个示例,但您可能需要做一些不同的事情。请注意,它修改了@items数组,每次@items的内容可能发生变化时,您都需要再次调用prepare

    my $sth = $dbh->prepare(
        sprintf "INSERT INTO grid ( %s, %s, %s ) values ( ?, ?, ? )",
        splice @items, 0, 3
    );
    my $rows = $sth->execute(@items);
    print "$rows affected\n";
    

    【讨论】:

    • 一句警告(尽管可能是迟到的):使用用户提供的列名执行此操作首先会破坏使用准备好的语句的目的,因为它会使您再次容易受到 SQL 注入的攻击.
    猜你喜欢
    • 2015-06-22
    • 2023-04-09
    • 2010-12-24
    • 2015-08-07
    • 2017-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多