2013-11-27 2 views
1

Я очень ценю вашу помощь по моему последнему вопросу. Это связано, но я не хотел скрывать этот вопрос внутри другого. У меня проблема с использованием «DATE_ADD (NOW(), INTERVAL $ interval)» внутри заполнителя. До того, как я использовал заполнители, эта линия работала отлично, а не возвращалась как пустая.mysql placeholder не работает для DATE_ADD (perl)

$store = qq(INSERT INTO main (creator_name,relationship,time) VALUES(?,?,?)); 

    my $sth = $dbh->prepare($store); 
    $sth->execute($data{creatorname},$data{relationship}, "DATE_ADD(NOW(), INTERVAL $interval)"); 

Есть ли другой способ добавить DATE_NOW, чтобы он был синтаксически правильным? Я попытался добавить его обратно как

 $store = qq(INSERT INTO main (creator_name,relationship,time) VALUES(?,?, DATE_ADD(NOW(), INTERVAL $interval))); 

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

+0

Что такое $ interval? – woolstar

+0

Трудно проверить исправление, не зная больше о вашей настройке, но на первый взгляд похоже, что вы смешиваете синтаксис SQL и значения заполнителя. Токены, такие как 'DATE_ADD' или' NOW', являются выражениями SQL, а не переменными. Каждый «?» -заполнитель - это резерв для одной скалярной переменной. Например, 'DATE_ADD (NOW(), интервал INTERVAL $) может стать' DATE_ADD (NOW(), INTERVAL?) 'С' $ interval' передан 'execute'. Прошлое, я ржав на функциях даты MySQL, но вам нужно [указать единицы на этом интервале] (http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions .html # function_date-надстройка)? – rutter

+1

@rutter, 'DATE_ADD (NOW(), INTERVAL?)' Не будет работать, потому что синтаксис - это DATE_ADD (NOW(), INTERVAL {expr} {unit}) '. Вы можете сделать DATE_ADD (NOW(), INTERVAL? WEEK) ', но не' DATE_ADD (NOW(), INTERVAL?) 'Или' DATE_ADD (NOW(), INTERVAL??) ' – ikegami

ответ

0

Ожидаете ли вы следующее: ABC?

$x = 'uc "abc"'; 
print $x; 

Нет, это не имело бы смысла. То же самое в SQL.

Строка DATE_ADD(NOW(), INTERVAL ...), безусловно, недействительна для поля time.


это ошибочный, говоря, синтаксис был неправ.

Я уверен, что сообщение было более конкретным. Вы также не указали значение $interval, без которого мы не знаем, что привело к синтаксической ошибке.

+0

Ошибка:« У вас есть ошибка в синтаксисе SQL, проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса, используемого рядом с «». Переменная $ interval содержит что-то в виде «1 WEEK» или «1 МЕСЯЦ». –

+0

Это не будет синтаксической ошибкой, но я проверю завтра, когда у меня будет доступ к MySQL, чтобы быть уверенным. В то же время, получите фактическое сообщение об ошибке для нас. – ikegami

0

Изменение QQ() к QQ {} для ясности, это должно быть исправление:

$store = qq{ 
    INSERT INTO main (creator_name,relationship,time) 
    VALUES(?, ?, DATE_ADD(NOW(), INTERVAL ? SECOND)) 
}; 

my $sth = $dbh->prepare($store); 
$sth->execute($data{creatorname},$data{relationship},$interval); 

Вам нужно изменить слово «ВТОРАЯ» в соответствующих единицах, и $ интервальные потребности в быть целым числом.

Претензии к использованию подготовленных инструкций, но причина, по которой это не работает так, как вы это пробовали, очень важно: заполнители ? - это не просто места, где в ваш запрос будет помещен произвольный текст. Вот почему мы делаем такое большое дело о важности использования подготовленных заявлений в качестве одного из способов защиты от SQL-инъекций. Заполнители - это жесткое разграничение между «тем, что является запросом» и «чем являются данные», и они отправляются на сервер отдельно, а не помечены вместе.

Таким образом ...

my $sth = $dbh->prepare(qq{SELECT * FROM user WHERE username = ? AND password = ?}); 
$sth->execute("hacker", "' OR 1 = 1; --"); 

... не может быть неправильно истолкован, чтобы стать страшился ...

SELECT * FROM user WHERE username = 'hacker' AND password = '' OR 1 = 1; --' 

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

Заполнитель заменяет ровно одно скалярное значение буква, которое «DATE_ADD (NOW(), INTERVAL $ interval)« нет. (Да, это скалярная строка в Perl, но она содержит выражение, а не буквальное значение).

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