我附上了以下代码,但我遇到了以下错误。任何人都可以解决问题的原因吗?
$DBH1->do("USE data_current;");
$stm1="select * from data_1m.wms where time =(select max(time) from wms)";
$stmt2="insert into data_current.wms(time,available,closed,used,busy,reserved,down) values(select * from data_1m.wms where time =(select max(time) from wms)";
my $sth1 = $DBH1->prepare( "$stmt1" );
$sth1->execute($stmt2) or print "Could not insert data";
$sth1->finish;
$DBH1->disconnect();
发生以下错误:
DBD :: mysql :: st执行失败:当0为0时,使用1个绑定变量调用 需要
答案 0 :(得分:3)
我担心我对one of my comments yesterday感到困惑。这就是我所说的:
看起来这与你的Perl无关。您的SQL返回了错误的数据(出于我不理解的原因)。这是做什么的。在源数据库上打开mysql会话。编写一个返回正确数据的SQL语句。将
insert into ...
子句添加到该SQL的前面。从Perl执行该SQL
我试图解开这里的误解。但是,考虑到我们在这个看似简单的任务上回答了多长时间,我想知道你是否有时间放弃并聘请程序员来为你做这件事。
此任务分为两个阶段。首先,您需要识别一个选择您感兴趣的数据的SQL语句。其次,您需要将select
语句转换为insert into ...
语句并从Perl程序中执行该语句。
对于第一阶段,您根本不需要Perl。您只需要一个连接到源数据库的mysql
命令行程序。然后,您可以尝试一些SQL语句,直到找到一个可以提供所需数据的语句。看起来你认为你需要的陈述是:
select *
from data_1m.wms
where time = (select max(time) from wms)
太棒了。我可能会对SQL进行两次调整。我明确列出了我选择的列,并且我指定了wms
表所在的数据库。所以它看起来像这样:
select time, available, closed, used, busy, reserved, down
from data_1m.wms
where time = (select max(time) from data_1m.wms)
现在我们需要将其转换为insert ...
语句。这可能看起来像这样:
insert into data_current.wms(time,available,closed,used,busy,reserved,down)
select time, available, closed, used, busy, reserved, down
from data_1m.wms
where time = (select max(time) from data_1m.wms)
(与您的情况略有不同 - 您在values
声明中不需要insert ... select ...
关键字。)
这就是你需要从你的Perl程序运行的东西。实际上,您可以先从mysql
命令行程序对其进行测试,以确保它能做正确的事情。
现在我们来解决你当前的问题。这就是我开始认为你可能最好还是让别人为你做这件事的原因 - 因为这个问题是由于你根本没有阅读(或不理解)DBI的基础知识引起的。
在DBI中运行查询是一个两阶段的过程。您prepare()
查询并返回一个语句句柄。然后,在该语句句柄上调用execute()
以实际执行查询。在文档中没有任何地方甚至暗示您可以在现有语句句柄上将另一个(新)语句传递给execute()
方法。如果要运行另一个语句,则需要prepare()
该语句获取新的语句句柄,然后在该语句句柄上运行execute()
。
(允许将参数传递给execute()
,以便定义插入到SQL中的"绑定点"中的值。这就是您遇到错误的原因。但是你没有使用绑定点。)
因此,要在代码中执行您想要执行的操作,您可以编写如下代码:
my $stm1="select * from data_1m.wms where time =(select max(time) from wms)";
my $stmt2="insert into data_current.wms(time,available,closed,used,busy,reserved,down) values(select * from data_1m.wms where time =(select max(time) from wms)";
my $sth1 = $DBH1->prepare( $stmt1 );
$sth1->execute() or print "Could not insert data";
$sth1->finish;
my $sth2 = $DBH1->prepare( $stmt2 );
$sth2->execute;
$sth2->finish;
$DBH1->disconnect();
但是(我希望我已经在上面说明了)你不需要这样做,因为$stmt1
是完全没必要的。另外(as Chankey points out)使用insert ...
方法运行do()
语句比prepare()
/ execute()
周期更容易。
答案 1 :(得分:1)
非SELECT语句的典型方法调用序列是:
prepare,
execute,
execute,
execute
现在您正在尝试将数据插入到表中,这是非SELECT语句。所以你应该遵循同样的方法。
1)准备声明
my $sth = $dbh->prepare("INSERT INTO...");
2)执行准备好的陈述
$sth->execute(); #pass @bind_values if there are any
或者您也可以使用do()
方法。
$rows_affected = $dbh->do("INSERT INTO ...");
请仔细阅读documentation of DBI了解详情。
DBD :: mysql :: st执行失败:当需要0时使用1个绑定变量调用
您收到上述错误是因为您正在将另一个语句传递给execute
方法,而execute
方法只接受绑定值,在您的情况下不是。