perl + postgresql 代码导致 Pg.pm 出现问题
perl + postgresql code results in problems with Pg.pm
我在尝试将数据插入 table 时遇到一个奇怪的错误,同时处理从另一个 table 获取的数据:
DBI::st=HASH(0x56261b345948)->_prepare(...): attribute parameter '0' is not a hash ref at /usr/lib/x86_64-linux-gnu/perl5/5.24/DBD/Pg.pm line 277.
似乎导致它的行是上面代码片段中的 $dbh->do():
my $sth = $dbh->prepare(
"SELECT (name, model), serial, firmware, timestamp FROM devicelog
WHERE id = $id AND fleet = $fleet AND timestamp >
(SELECT timestamp FROM devicelog WHERE fleet = $fleet AND id = $id ORDER BY timestamp DESC LIMIT 1)
- INTERVAL '50 seconds'"
);
$sth->execute();
while (my @row = $sth->fetchrow_array())
{
if (param('savetemplate'))
{
$dbh->do('INSERT INTO template (fleet, id, name, model, serial) VALUES (?, ?, ?, ?, ?)',
$fleet,
$id,
$row[0],
$row[1],
$row[2]
) or die $!;
}
# Do some printing to screen and other mundane stuff
}
我查看了第一个 SQL 查询返回的数据,但我找不到任何问题,因为结果符合预期结果:
row | serial | firmware | timestamp
----------------------------------------+-----------+---------------------+----------------------------
("HS60 GPS COMPASS",000-12308-001) | 19030590# | 01000023 | 2017-11-12 00:08:01.435483
("IS42 Instrument","") | 007564# | 01000_E 1.0.54.3.21 | 2017-11-12 00:08:01.476376
我开始认为应该转义的东西不是吗?我还怀疑 DBI 可能不喜欢 运行 a do() 同时仍在迭代 fetchrow_array()
系列,但重写以避免同时执行它会产生相同的结果。
如果需要更多信息,请发表评论,我会提供。
根据the documentation,do
有以下形式:
do
$rows = $dbh->do($statement) or die $dbh->errstr;
$rows = $dbh->do($statement, \%attr) or die $dbh->errstr;
$rows = $dbh->do($statement, \%attr, @bind_values) or die ...
您的代码:
$dbh->do('INSERT INTO template (fleet, id, name, model, serial) VALUES (?, ?, ?, ?, ?)',
$fleet,
$id,
$row[0],
$row[1],
$row[2]
)
这将 $fleet
(第二个参数)视为对属性散列(\%attr
参数)的引用,但事实并非如此(它是一个数字)。你不想传递任何属性,所以你应该指定 undef
:
$dbh->do('INSERT INTO template (fleet, id, name, model, serial) VALUES (?, ?, ?, ?, ?)',
undef,
$fleet,
$id,
$row[0],
$row[1],
$row[2],
)
另请注意,DBI 不会设置 $!
,因此在错误消息中使用它意义不大。您应该改用 $dbh->errstr
(或者只是在 connect
调用中传递 RaiseError => 1
以使所有方法在出错时抛出异常)。
我在尝试将数据插入 table 时遇到一个奇怪的错误,同时处理从另一个 table 获取的数据:
DBI::st=HASH(0x56261b345948)->_prepare(...): attribute parameter '0' is not a hash ref at /usr/lib/x86_64-linux-gnu/perl5/5.24/DBD/Pg.pm line 277.
似乎导致它的行是上面代码片段中的 $dbh->do():
my $sth = $dbh->prepare(
"SELECT (name, model), serial, firmware, timestamp FROM devicelog
WHERE id = $id AND fleet = $fleet AND timestamp >
(SELECT timestamp FROM devicelog WHERE fleet = $fleet AND id = $id ORDER BY timestamp DESC LIMIT 1)
- INTERVAL '50 seconds'"
);
$sth->execute();
while (my @row = $sth->fetchrow_array())
{
if (param('savetemplate'))
{
$dbh->do('INSERT INTO template (fleet, id, name, model, serial) VALUES (?, ?, ?, ?, ?)',
$fleet,
$id,
$row[0],
$row[1],
$row[2]
) or die $!;
}
# Do some printing to screen and other mundane stuff
}
我查看了第一个 SQL 查询返回的数据,但我找不到任何问题,因为结果符合预期结果:
row | serial | firmware | timestamp
----------------------------------------+-----------+---------------------+----------------------------
("HS60 GPS COMPASS",000-12308-001) | 19030590# | 01000023 | 2017-11-12 00:08:01.435483
("IS42 Instrument","") | 007564# | 01000_E 1.0.54.3.21 | 2017-11-12 00:08:01.476376
我开始认为应该转义的东西不是吗?我还怀疑 DBI 可能不喜欢 运行 a do() 同时仍在迭代 fetchrow_array()
系列,但重写以避免同时执行它会产生相同的结果。
如果需要更多信息,请发表评论,我会提供。
根据the documentation,do
有以下形式:
do
$rows = $dbh->do($statement) or die $dbh->errstr; $rows = $dbh->do($statement, \%attr) or die $dbh->errstr; $rows = $dbh->do($statement, \%attr, @bind_values) or die ...
您的代码:
$dbh->do('INSERT INTO template (fleet, id, name, model, serial) VALUES (?, ?, ?, ?, ?)',
$fleet,
$id,
$row[0],
$row[1],
$row[2]
)
这将 $fleet
(第二个参数)视为对属性散列(\%attr
参数)的引用,但事实并非如此(它是一个数字)。你不想传递任何属性,所以你应该指定 undef
:
$dbh->do('INSERT INTO template (fleet, id, name, model, serial) VALUES (?, ?, ?, ?, ?)',
undef,
$fleet,
$id,
$row[0],
$row[1],
$row[2],
)
另请注意,DBI 不会设置 $!
,因此在错误消息中使用它意义不大。您应该改用 $dbh->errstr
(或者只是在 connect
调用中传递 RaiseError => 1
以使所有方法在出错时抛出异常)。