使用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();
答案 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,但这在过去帮助了我很多。
干杯。