У меня есть SQL-оператор, подобный один показанный ниже в Perl:
my $sql="abc..TableName '$a','$b' ";
$a является произвольным текстом, который может содержать что-либо включая одинарные кавычки, двойные кавычки, назад - и символы передней наклонной черты, и т.д.
Как этих символов можно оставить, чтобы заставить SQL-оператор работать?
Спасибо.
Можно использовать метод -> quote
(в предположении, что вы используете DBI):
my $oldValue = $dbh->quote('oldValue');
my $newValue = $dbh->quote('newValue');
$dbh->do("UPDATE myTable SET myValue=$newValue where myValue=$oldValue");
Лучше всего использовать значения привязки:
my $sth = $dbh->prepare('UPDATE myTable SET myValue=? WHERE myValue=?');
$sth->execute('newValue','oldValue');
Это также должно работать при вызове хранимых процедур, в предположении, что оператор после расширения строк является действительным SQL. Это может быть специфично для драйвера/базы, поэтому YMMV.
my $sth = $dbh->prepare("DBName..ProcName ?,? ");
$sth->execute($a, $b);
Используйте подготовленное заявление. Замените переменную на ?. Чтобы списать пример из DBI manpages:
$sql = 'SELECT * FROM people WHERE lastname = ?';
$sth = $dbh->prepare($sql);
$sth->execute($user_input_here);
Интерполяция пользовательского ввода в SQL запрашивает дыры в безопасности.
.Если используются плейсхолдеры параметров запроса, то нет необходимости экранировать содержимое строк.
my $sql="DBName..ProcName ?, ?";
$sth = $dbh->prepare($sql);
$sth->execute($a, $b);
Если в СУБД используются истинные параметры запроса, то она посылает значения параметров в СУБД отдельно от SQL-оператора. Значения никогда не комбинируются со строкой SQL-оператора, поэтому у значений никогда нет возможности вызвать SQL-инъекцию.
Если БДИ "эмулирует" подготовленные операторы, интерполируя переменные в строку запроса, то БДИ должна обрабатывать корректную логику экранирования, чтобы не пришлось. Пусть эксперты (те, кто пишет и тестирует DBI) позаботятся о том, как это сделать.
.Если вы не хотите использовать -> кавычки (по каким-то причинам эта функция не работает на моей версии DBI), тогда попробуйте следующее:
$query=~s/\"/\\\"/g;
Я склонен делать то же самое с одиночными кавычками и запятыми тоже, просто для безопасности.
Похоже, для меня это отлично работает...!