Почему мой INSERT иногда терпит неудачу с "нет такого поля"? - PullRequest
2 голосов
/ 30 ноября 2008

Я использовал следующий фрагмент кода в разработке в течение многих лет. Теперь внезапно я получаю сообщение об ошибке БД: такого предупреждения нет

$process = "process";
$create = $connection->query
(
    "INSERT INTO summery (process) VALUES($process)"
);
if (DB::isError($create)) die($create->getMessage($create));

но хорошо, если я использую цифры

$process = "12345";
$create = $connection->query
(
    "INSERT INTO summery (process) VALUES($process)"
);
if (DB::isError($create)) die($create->getMessage($create));

или запишите значение непосредственно в выражение

$create = $connection->query
(
    "INSERT INTO summery (process) VALUES('process')"
);
if (DB::isError($create)) die($create->getMessage($create));

Я действительно запутался ... есть предложения?

Ответы [ 2 ]

7 голосов
/ 30 ноября 2008

Всегда лучше использовать подготовленные запросы и заполнители параметров. Как в Perl DBI:

my $process=1234;
my $ins_process = $dbh->prepare("INSERT INTO summary (process) values(?)");
$ins_process->execute($process);

Для лучшей производительности подготовьте все ваши часто используемые запросы сразу после открытия соединения с базой данных. Многие движки баз данных будут хранить их на сервере во время сеанса, как маленькие временные хранимые процедуры.

Это также очень хорошо для безопасности. Запись значения в строку вставки самостоятельно означает, что вы должны написать правильный escape-код в каждом операторе SQL. Использование стиля подготовки и выполнения означает, что только одно место (выполнение) должно знать о побеге, если побег даже необходим.

0 голосов
/ 01 декабря 2008

То же самое сказал Зан Линкс о заполнителях. Но вы можете все еще задаться вопросом, почему ваш код не удался.

Похоже, что вы забыли важную деталь из предыдущего кода, который работал у вас годами: цитаты.

Этот (проверенный) код отлично работает:

my $thing = 'abcde';
my $sth = $dbh->prepare("INSERT INTO table1 (id,field1)
                              VALUES (3,'$thing')");
$sth->execute;

Но следующий код (без кавычек в поле VALUES, как в первом примере) создает ошибку, о которой вы сообщаете, потому что VALUES (3, $ thing) разрешается в VALUES (3, abcde), заставляя ваш SQL-сервер выглядеть для поля с именем abcde, и нет поля с таким именем.

my $thing = 'abcde';
my $sth = $dbh->prepare("INSERT INTO table1 (id,field1)
                              VALUES (3,$thing)");
$sth->execute;

Все это предполагает, что ваш первый пример не является прямой цитатой кода, который потерпел неудачу, как вы описываете, и, следовательно, не соответствует тому, что вы намеревались. Он разрешает:

"INSERT INTO summery (process) VALUES(process)"

, который, как упоминалось выше, заставляет ваш SQL-сервер читать элемент в ЗНАЧЕНИЯХ, заданных как другое имя поля. Как указано, это фактически выполняется на MySQL без жалоб и заполнит поле с именем «process» значением NULL, потому что это то, что содержится в поле с именем «process», когда MySQL искал там значение при создании новой записи.

Я использую этот стиль для быстрых одноразовых взломов, включающих известные защищенные данные (например, значение, предоставленное в самой программе). Но для всего, что связано с данными, которые поступают из-за пределов программы или могут содержать какие-либо данные, кроме [0-9a-zA-Z], вам не придется использовать заполнители.

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