2008-11-30 6 views
2

Я использую следующий фрагмент в разработке в течение многих лет. Теперь вдруг я получаю DB Error: нет такого поля предупреждениеПочему мой INSERT иногда терпит неудачу с «нет такого поля»?

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

Я действительно смущен ... любые предложения?

+0

Это было бы очень полезно для читателей, и вы получили бы более значимые и точные ответы, если бы указали имя используемого вами API БД. – converter42 2008-11-30 19:47:45

ответ

7

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

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

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

Его также очень хорошо для безопасности. Написание значения в строке вставки означает, что вы должны написать правильный код возврата в каждом операторе SQL. Использование стиля «Подготовить и выполнить» означает, что только место (выполнение) должно знать об экранировании, если требуется экранирование.

0

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

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

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

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

Но следующий код (отсутствие кавычек в поле VALUES только в качестве первого примера делает) производит ошибку вы сообщаете, потому что ЗНАЧЕНИЯ (3, $ вещь) разрешает 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, потому что это то, что поле называло «процессом», когда MySQL выглядел там для значения, поскольку он создал новую запись.

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

Смежные вопросы