Как избежать встроенной функции SQL в perl bind_param ()? - PullRequest
1 голос
/ 15 января 2010

Итак, у меня есть следующий код:

my $sql = "INSERT INTO mytbl (first_name, last_name, birthdate) VALUES (?, ?, ?)";
my $sth = $dbh->prepare($sql) or die "Error:".$dbh->errstr;                 

$sth->bind_param(1, $fname);
$sth->bind_param(2, $lname);
$sth->bind_param(3, $bdate);
$sth->execute() or die "Execution failed: " . $dbh->errstr;
$sth->finish();

При выполнении вставки в Microsoft SQL со следующими данными для даты рождения, $ bdate = "2010-01-06"; Я должен привести его к функции datetime с SQL,

$bdate = "cast ('$eml_form_end_dt' as datetime)";

Это, однако, вызвало проблему, поскольку Perl не распознает ее. Вместо этого я должен был:

$bdate = "cast ('$eml_form_end_dt' as datetime)";
my $sql = "INSERT INTO mytbl (first_name, last_name, birthdate VALUES (?, ?, '$bdate')";
my $sth = $dbh->prepare($sql) or die "Error:".$dbh->errstr;                 

$sth->bind_param(1, $fname);
$sth->bind_param(2, $lname);
# This causes problem
# $sth->bind_param(3, "cast ('$eml_form_end_dt' as datetime)");
$sth->execute() or die "Execution failed: " . $dbh->errstr;
$sth->finish();

Как мне избежать функции SQL в этом случае?

РЕДАКТИРОВАТЬ: это сообщение об ошибке, которое я получил: DBD :: ODBC :: st выполнить не удалось: [Microsoft] [Драйвер ODBC SQL Server] Недопустимая точность по значению (SQL-HY104) в filename.pl.

Ответы [ 4 ]

2 голосов
/ 16 января 2010

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

my $sql = "INSERT INTO mytbl (first_name, last_name, birthdate VALUES (?, ?, cast(? as datetime))";
my $sth = $dbh->prepare($sql) or die "Error:".$dbh->errstr;                 

$sth->bind_param(1, $fname);
$sth->bind_param(2, $lname);
$sth->bind_param(3, $eml_form_end_dt);
$sth->execute() or die "Execution failed: " . $dbh->errstr;
$sth->finish();

Это должно сработать.

0 голосов
/ 18 января 2010

Не должно ли это:

INSERT INTO mytbl (first_name, last_name, birthdate VALUES (?, ?, cast(? as datetime))

быть таким:

INSERT INTO mytbl (first_name, last_name, birthdate) VALUES (?, ?, cast(? as datetime))

0 голосов
/ 15 января 2010

Я почти уверен, что MS SQL преобразует строку в дату без приведения. У вас была проблема с привязкой '2010-01-06' к заполнителю? Если это не сработает, вы можете использовать 3-й аргумент bind_param, чтобы указать тип аргумента. Или вы можете попробовать:

my $sql = "INSERT INTO mytbl (first_name, last_name, birthdate) VALUES (?, ?, cast(? as datetime))";

и привязать строковую версию даты к этому заполнителю.

Обновление: Удивительно, сколько людей (включая меня) пропустили пропавшего правого парня.

0 голосов
/ 15 января 2010

Я думаю, что вы действительно хотите

use DBI qw(:sql_types);
...
$sth->bind_param(3, $bdate, SQL_DATETIME);

, чтобы указать DBI правильный тип для использования (по умолчанию varchar). Возможно, вам придется использовать SQL_DATE вместо SQL_DATETIME; Я сам не пользуюсь SQL Server.

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