如何在Perl DBI查询中插入带引号的字符串?

时间:2008-11-12 17:50:21

标签: mysql perl

使用DBI将可以包含单引号和双引号(“,”)的字符串插入MySql的首选方法是什么?例如,$val1$val2可以包含引号:

my $dbh = DBI->connect( ... );
my $sql = "insert into tbl_name(col_one,col_two) values($val1, $val2)";
my $sth = $dbh->prepare($sql);
$sth->execute();

4 个答案:

答案 0 :(得分:25)

使用

使用绑定查询
$sth = $dbh->prepare("insert into tbl_name(col_one,col_two) values(?,?)");
$sth->execute($val1, $val2);

如果您使用绑定变量,则会为您转义所有内容。

更新:更改了我的示例以与编辑到问题中的示例相对应。

更新:我不知道亚当为什么删除了他的答案,但如果由于某种原因你不能使用绑定变量(又名“占位符”),你也可以在变量上使用$dbh->quote($var)。例如:

$sql = sprintf "SELECT foo FROM bar WHERE baz = %s",
    $dbh->quote(q("Don't"));

答案 1 :(得分:3)

使用quote()方法。它会智能地为您处理报价。 docs的示例:

$sql = sprintf "SELECT foo FROM bar WHERE baz = %s",
            $dbh->quote("Don't");

略微修改以具有两种类型的引号:

$sql = sprintf "SELECT foo FROM bar WHERE baz = %s",
            $dbh->quote(q("Don't"));

答案 2 :(得分:2)

关于绑定占位符的一个小警告,我构建了一个相当大的数据库加载脚本,该脚本最初在旧版本的Perl / DBI中使用绑定占位符,并发现占位符实现中的内存泄漏,所以如果你我们正在考虑在持久进程/守护进程中或在高容量上下文中使用它们,您可能希望确保进程大小不会成为问题。使用quote()方法切换到构建查询字符串可以解决我的问题。

答案 3 :(得分:0)

DBI占位符非常棒。当您需要在循环中执行相同的查询时,它们会闪耀。考虑一下:

  my $dbh = DBI->connect(...);
  my $name_pairs = get_csv_data("data.csv");
  my $sth = $dbh->prepare("INSERT INTO t1 (first_name, last_name) VALUES (?,?)");
  for my $pair (@$name_pairs) {
     unless ($sth->execute(@$pair)) {
         warn($sth->errstr);
     }
  }

在这种情况下,准备好语句句柄是呃,方便。

但是,除了这种紧密循环的情况,我喜欢看到发送到服务器的实际语句。这是我严重依赖引用并坦率地sprintf的地方。

   # Here, I am confident about the hash keys, less so about the values
   $sql = sprintf("INSERT INTO t1 (%s) VALUES (%s)",
                    join(",", keys(%hash)),
                    join("," map { $dbh-quote($_) } values(%hash))
                  );
   $sth = $dbh->prepare($sql);
   unless ($sth->execute) {
     warn($sth->{Statement});
   }

请注意,您必须设置RaiseError =>在$ dbh上0,这样你就可以看到失败的SQL,但这在过去帮助了我很多。

干杯。