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

Mysql 如何在Perl DBI查询中插入带引号的字符串?,mysql,perl,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(); 使用绑定查询 $sth = $dbh->pr

使用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();

使用绑定查询

$sth = $dbh->prepare("insert into tbl_name(col_one,col_two) values(?,?)");
$sth->execute($val1, $val2);
如果使用绑定变量,则所有内容都将转义

更新:将我的示例更改为与编辑到问题中的示例相对应

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

$sql = sprintf "SELECT foo FROM bar WHERE baz = %s",
    $dbh->quote(q("Don't"));
使用
quote()
方法。它将为您智能地处理报价。例如:

稍作修改,以包含两种类型的引号:

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

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

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);
     }
  }
在这种情况下,拥有准备好的语句句柄是非常方便的

但是,除非出现这种紧密循环的情况,否则我希望看到发送到服务器的实际语句。这就是我非常依赖quote和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});
   }
注意,您必须在$dbh上设置RaiseError=>0,以便查看失败的SQL,但这在过去对我帮助很大


干杯。

这通常被称为使用占位符。占位符还具有防止SQL注入攻击的非常有用的属性。始终使用它们。永远不要将用户提供的数据直接放入查询中。“executeUpdate”应该只是“执行”(而且它是插入,而不是更新:-)顺便说一句,Adam,quote()这也是一个很好的答案,有时它比占位符更可取。但是,是的,永远不要在查询中直接使用用户提供的数据,或者遭受Bobby Tables的愤怒。@Adam你不应该删除你的答案。它有一些常见的信息。有趣的是,可能只是因为语句句柄对象是cre显然,这导致了Perl中的内存管理问题,即内存碎片。Perl真的不太擅长回收释放的内存……我也不记得为什么删除了这个答案。因此,我正在取消删除它。:)不清楚为什么这个准确、礼貌的答案被否决了,但是什么呢。
   # 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});
   }