Как я могу вставить строки с кавычками в запросы Perl DBI? - PullRequest
6 голосов
/ 12 ноября 2008

Каков предпочтительный способ вставки строк, которые могут содержать одинарные и двойные кавычки (", ') в MySql с использованием DBI? Например, $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 ]

25 голосов
/ 12 ноября 2008

Используйте связанный запрос, используя

$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"));
3 голосов
/ 12 ноября 2008

Используйте метод quote(). Он будет разумно обрабатывать цитаты для вас. Пример из документов :

$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 голосов
/ 13 ноября 2008

Одна небольшая оговорка о связанных заполнителях, я построил довольно большой скрипт загрузки базы данных, который первоначально использовал связанные заполнители в более старой версии Perl / DBI и обнаружил, что в реализации заполнителей есть утечка памяти, так что Если вы хотите использовать их в постоянном процессе / демоне или в контексте большого объема, вы можете убедиться, что размер процесса не станет проблемой. Переход к построению строк запроса с использованием метода quote () устранил проблему для меня.

0 голосов
/ 23 мая 2018

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);
     }
  }

В этом случае удобнее иметь подготовленный дескриптор оператора.

Однако, за исключением случаев подобного рода замкнутых циклов, мне нравится видеть фактическое утверждение, которое было отправлено на сервер. Вот где я сильно опираюсь на цитаты и откровенно бегу.

   # 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 => 0 в $ dbh, чтобы вы могли видеть SQL, который не прошел, но это помогло мне в прошлом.

Приветствие.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...