2016-11-10 3 views
0

次のコードを添付しましたが、次のエラーが発生しました。問題の原因を解決できるのは誰ですか?perlを使用して変数に格納されたmysqlクエリを使用しているときにバインドパラメータエラーが発生しますか?

$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 がため

+2

$ sth1-> execute($ stmt2)なぜ$ stmt1に$ stmt2をパラメータとして渡していますか? – e4c5

+0

$ stmt2 @ e4c5として渡すように$ stmt2クエリを実行したい –

+1

準備と実行のドキュメントを読むのに30秒を費やすという簡単なことです – e4c5

答えて

1

典型的なメソッドの呼び出しシーケンス必要です1つのバインド変数と呼ばれます非SELECTステートメントは:

prepare, 
    execute, 
    execute, 
    execute 

あなたはテーブルにデータを挿入しようとしていますが、それは非SELECTステートメントです。したがって、同じアプローチをとるべきです。

1)別の方法として、あなたもdo()メソッドを使用することができ

$sth->execute(); #pass @bind_values if there are any 

プリペアドステートメントを実行する)

my $sth = $dbh->prepare("INSERT INTO..."); 

2文を準備します。

$rows_affected = $dbh->do("INSERT INTO ..."); 

詳細については、documentation of DBIをご覧ください。


DBD :: mysqlのは:: stが失敗した実行:0

を必要なときに1つのバインド変数と呼ばれるあなたがexecuteメソッドに別の文を渡しているので、あなたが上記のエラーを取得しています、一方executeメソッドはバインド値のみを受け入れますが、あなたの場合はnoneです。

3

私は恐らくone of my comments yesterdayとあなたを混乱させてしまいます。私が言ったことはここにあります:

これはあなたのPerlとは関係ないようです。あなたのSQLは間違ったデータを返しています(わからない理由があります)。ここで何をするのですか?ソースデータベースでmysqlセッションを開きます。正しいデータを返すSQL文を作成します。そのSQLの先頭にinsert into ...句を追加します。 PerlからそのSQLを実行してください

ここでは誤解を解消しようとします。しかし、この一見単純な作業で、私たちがどれくらいの時間の質問に答えているかを考えれば、あきらめてプログラマを雇って、あなたのためにこれを行うことが必要なのでしょうか?

このタスクには2つのフェーズがあります。最初に、興味のあるデータを選択するSQL文を特定する必要があります。次に、select文をinsert into ...文に変換し、その文をPerlプログラムから実行する必要があります。

最初の段階では、Perlはまったく必要ありません。ソースデータベースに接続されているmysqlコマンドラインプログラムが必要です。次に、必要なデータを提供するSQLステートメントを見つけるまで、いくつかのSQLステートメントを試してみましょう。あなたが必要とする声明が次のようなものだと思われます:

select * 
from data_1m.wms 
where time = (select max(time) from wms) 

これは素晴らしいことです。私はおそらくそのSQLに2つの微調整を行うでしょう。私は明示的に私が選択してるの列をリストしたいと私はwms表が入っているデータベースを指定したい、それは次のようになりますので:。

select time, available, closed, used, busy, reserved, down 
from data_1m.wms 
where time = (select max(time) from data_1m.wms) 

は、今、私たちはinsert ...ステートメントにそれを変換する必要があります。 (それはあなたが持っていたものとは若干異なるです - あなたはinsert ... select ...文でvaluesキーワードを必要としません。)

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) 

だからそれはあなたがあなたのPerlから実行するために必要なものです:それはおそらく、このようになりますプログラム。実際には、コマンドラインプログラムのmysqlからテストして、正しいことを確認することができます。

今、あなたの現在の問題が発生しています。これは、あなたがDBIの基本を読んでいない(または理解していない)ことに起因するため、他の人にあなたに代わって支払う方が良いと思うところです。

DBIでクエリを実行することは、2段階のプロセスです。クエリーをprepare()すると、ステートメントハンドルが返されます。そのステートメント・ハンドルで​​を呼び出して、実際に照会を実行します。ドキュメントのどこにも、別の(新しい)ステートメントを既存のステートメントハンドルの​​メソッドに渡すことができるというヒントもありません。別のステートメントを実行する場合は、そのステートメントで新しいステートメント・ハンドルを取得し、そのステートメント・ハンドルで​​を実行する必要があります。

(​​にパラメータを渡すが、あなたがやったエラーを得た理由です。あなたの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 outinsert ...ステートメントをdo()メソッドを使用して実行するのは、prepare()/​​サイクルよりはるかに簡単です。

私の昨日のコメントがあなたを混乱させた場合は、お詫び申し上げます。私は本当に可能な限り明確にしようとしました。しかし、私は本当にこの問題を続ける前に、一歩踏み込んで深呼吸をする必要があると思います。あなたがランダムに物事を変えることによってプログラミングしているように、少し見えるようになっています。それは決して良いアプローチではありません。

関連する問題