如何在SQL预处理语句中转义单引号和双引号?

Sam*_*Sam 9 sql string quotes perl sybase

我有一个类似于下面Perl中的SQL语句:

my $sql="abc..TableName '$a','$b' ";
Run Code Online (Sandbox Code Playgroud)

$ a是自由文本,可以包含任何内容,包括单引号,双引号,反斜杠和斜杠字符等.

如何转义这些字符以使SQL语句有效?

谢谢.

mop*_*oke 21

您可以使用该->quote方法(假设您使用的是DBI):

my $oldValue = $dbh->quote('oldValue');
my $newValue = $dbh->quote('newValue');
$dbh->do("UPDATE myTable SET myValue=$newValue where myValue=$oldValue");
Run Code Online (Sandbox Code Playgroud)

更好的是,最好的做法是使用绑定值:

my $sth = $dbh->prepare('UPDATE myTable SET myValue=? WHERE myValue=?');

$sth->execute('newValue','oldValue');
Run Code Online (Sandbox Code Playgroud)

这也适用于存储过程调用,假设字符串扩展后的语句是有效的SQL.这可能是驱动程序/数据库特定的YMMV.

my $sth = $dbh->prepare("DBName..ProcName ?,? ");
$sth->execute($a, $b);
Run Code Online (Sandbox Code Playgroud)

  • 使用绑定参数仍应适用于存储过程调用. (5认同)

小智 9

使用准备好的声明.用?替换变量.从DBI联机帮助页中获取示例:

$sql = 'SELECT * FROM people WHERE lastname = ?';
$sth = $dbh->prepare($sql);
$sth->execute($user_input_here);
Run Code Online (Sandbox Code Playgroud)

将用户输入插入到SQL中会引发安全漏洞.


Bil*_*win 6

如果使用查询参数占位符,则不必转义字符串的内容.

my $sql="DBName..ProcName ?, ?";
$sth = $dbh->prepare($sql);
$sth->execute($a, $b);
Run Code Online (Sandbox Code Playgroud)

如果DBI使用true查询参数,它会将参数值与SQL语句分开发送到RDBMS.这些值永远不会与SQL语句字符串组合在一起,因此这些值永远不会有机会导致SQL注入.

如果DBI通过将变量插入到查询字符串中来"模拟"预处理语句,那么DBI应该处理正确的转义逻辑,因此您不必这样做.让专家(编写和测试DBI的人)担心如何做到这一点.