我在更新表时一直在尝试使用sql NOW()函数。但是那个日期字段没有任何反应,我认为DBI只是忽略了这个价值。代码是:
dbUpdate($id, (notes => 'This was an update', filesize => '100.505', dateEnd => 'NOW()'));
,功能是:
sub dbUpdate {
my $id = shift;
my %val_hash = @_;
my $table = 'backupjobs';
my @fields = keys %val_hash;
my @values = values %val_hash;
my $update_stmt = "UPDATE $table SET ";
my $count = 1;
foreach ( @fields ) {
$update_stmt .= "$_ = ? ";
$update_stmt .= ', ' if ($count != scalar @fields);
$count++;
}
$update_stmt .= " WHERE ID = ?";
print "update_stmt is : $update_stmt\n";
my $dbo = dbConnect();
my $sth = $dbo->prepare( $update_stmt );
$sth->execute( @values, $id ) or die "DB Update failed : $!\n";
$dbo->disconnect || die "Failed to disconnect\n";
return 1;
}#dbUpdate
正如您所看到的,这是sql查询的“动态”生成,因此我不知道sql日期函数(如now())的位置。
在给定的示例中,sql查询将是
UPDATE backupjobs SET filesize = ? , notes = ? , dateEnd = ? WHERE ID = ?
使用参数值
100.55, This was an update, NOW(), 7
但是日期栏仍然显示0000-00 -...
任何想法如何解决这个问题?
答案 0 :(得分:4)
我在更新表时一直在尝试使用sql NOW()函数。但 那个日期字段没有任何反应,我认为DBI只是忽略了这一点 值。
不,它没有。但是当您实际尝试添加字符串NOW()
时,数据库认为您正在提供日期时间或时间戳数据类型。那当然不行。不幸的是,DBI找不到你的意思。它所做的只是将?
更改为它所获得的字符串的转义(通过$dbh->quote()
)版本。
你可以做几件事:
以适当的格式提供当前时间戳字符串,而不是字符串NOW()
。
如果您有空,可以像这样使用DateTime::Format::MySQL
:
use DateTime::Format::MySQL;
dbUpdate(
$id,
(
notes => 'This was an update',
filesize => '100.505',
dateEnd => DateTime::Format::MySQL->format_datetime(DateTime->now),
)
);
如果没有,请使用DateTime
或Time::Piece
。
use DateTime;
my $now = DateTime->now->datetime;
$now =~ y/T/ /;
dbUpdate(
$id,
(notes => 'This was an update', filesize => '100.505', dateEnd => $now));
告诉您的dbUpdate
函数查找NOW()
之类的内容并做出相应的反应。
你可以这样做。但是有更好的方法可以对此进行编码。您还应该考虑例如CURRENT_TIMESTAMP()
也是如此。
sub dbUpdate {
my $id = shift;
my %val_hash = @_;
my $table = 'backupjobs';
my $update_stmt = "UPDATE $table SET ";
# Check for the NOW() value
# This could be done with others too
foreach ( keys %val_hash ) {
if ($val_hash{$_} =~ m/^NOW\(\)$/i) {
$update_stmt .= "$_ = NOW()";
$update_stmt .= ', ' if scalar keys %val_hash > 1;
delete $val_hash{$_};
}
}
# Put everything together, join keeps track of the trailing comma
$update_stmt .= join(', ', map { "$_=?" } keys %val_hash );
$update_stmt .= " WHERE ID = ?";
say "update_stmt is : $update_stmt";
say "values are: ", join(', ', values %val_hash);
my $dbo = dbConnect();
my $sth = $dbo->prepare( $update_stmt );
$sth->execute( values %val_hash, $id ) or die "DB Update failed : $!\n";
$dbo->disconnect || die "Failed to disconnect\n";
return 1;
}
自己撰写查询。
你可能不会这样做,我不会添加一个例子,因为你知道怎么做。
以下是其他内容:这是您在程序运行时对数据库执行的唯一操作吗?每次进行查询时连接和断开数据库都是不明智的。一旦你需要它(或者在程序开始时,如果你总是使用它),那么连接数据库的性能会更好,只需在任何地方使用这个dbh / dbo。它节省了大量的时间(和代码)。
答案 1 :(得分:3)
很抱歉,您无法使用NOW()
作为内插值。
当在SQL语句中使用?
时,相应的值(通过某种机制或其他)传递给数据库转义,因此无论什么值被解释为字符串,而不是SQL。因此,您实际上尝试使用字符串'NOW()'
作为日期值,而不是函数NOW()
。
要将NOW()
用作函数,您必须将其插入SQL本身,而不是将其作为绑定值传递。这意味着您将不得不使用dbupdate
函数的hack或编写新函数,或者在perl中将字符串作为字符串获取,并将结果字符串传递给dbupdate
。