- ベストアンサー
WebSQL 複数のデーターを引っ張る方法
- Webアプリを開発しておりまして、SQLに詳しい方にDB回りをお願いしいますが、WebSQLを使って名簿のようなテーブルから、該当するデーターをループを組んで読みだそうとしていますが、最後のデーターしか返ってきません。
- 目的は、該当する名前を表示して、それぞれに付加(追加する:空のテーブルは用意しておいて)データーを入力して、DBへ返そうと思っています。
- SQLの超初心者のため、またWebSQLやSQLiteも始めたばかりで、簡単にループを掛けてインクリメントで読み出し、表示して行きません。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
websql での関数が callback であるところ、結構混乱しますね。 プレースホルダーに入れるデータを、わざわざ変数に入れ替えてるのが仇になってるんじゃないかな。callback関数は、非同期 つまり元の呼び出し時のデータではなく、その変数が最終的に持ってる値をみると言うこと。local 変数で渡すのは、メモリリークの原因にもなって危ないみたいです。 補足のスクリプトにコメント追加してみました。 for (var i=0:i<dt.length;i++) { // var cd=dt[i][0]; // 不要 // var nm=dt[i][1]; // 不要 db.transaction( function(tx) { tx.executeSql( /* "insert into 対象 (番号,名称) values(?,?)",[cd,nm], // ← ここ cd, nm は、変数の参照が渡されているので、実際の実行時には、最終値 つまり dt[n-1][] の値になってしまう ↓ 配列 dt[i] で入力すれば、とりあえずこの関数全体が終了するまでは、個別に違うメモリ位置を見てくれるはず。 */ "insert into 対象 (番号,名称) values(?,?)",dt[i], function(tx,rs) {}, fiunction(tx,er) {alert(er.message);} ); }, function(er) {alert(er.message);}, function() {} ); }
その他の回答 (2)
- mpro-gram
- ベストアンサー率74% (170/228)
投稿してからもう一回見直していたら、 dt[i] の iもlocal変数だった、 i がn-1 まで回りきってから、callbackが呼ばれるので、callback 関数にもう一つかぶせないといけない db.transaction( (function(x1,x2){ /* データの受け渡し用wrapper関数と引数 */ return function(tx) { tx.executeSql( "insert into 対象 (番号,名称) values(?,?)",[x1,x2], function(tx,rs) {}, function(tx,er) {alert(er.message);} ); /* tx.executeSql の閉じ */ }; /* return するcallback 関数の閉じ */ })(cd,nm) , /* wrapper関数に渡すデータの指定。これは、 db.transaction が呼ばれた時点の変数値が入る */ function(er) {alert(er.message)}, function() {} ); /* transaction メソッドの閉じ */ ※ ()や{} の多重入れ子で括りの対応が解らなくなるので、全角空白でインデントしてます。コピー時は、半角に変換してください。 実行チェックしてないので、まだ間違いがあるかも?
お礼
丁寧に説明いただきありがとうございます DB担当の人に変更して実行してもらいます
- akito0417
- ベストアンサー率20% (55/266)
実行してるSQL文がないとなんとも言えないと思いますが。
お礼
もう一つ補足の欄がないので、現状をここに記載しますので、よろしくお願いします。 以下 dbはオープン済みのデータベースオブジェクトとする。 dtは要素が[番号,名称]の2要素からなる配列の可変長配列とする。 (selectbox等で設定済みとする) テーブル「対象」は create table 対象(番号 varchar(4),名称 varchar(20)) で生成されている(行データは存在しない)ものとする。 問題は配列dtの内容をテーブル「対象」に追加することである。 for (var i=0:i<dt.length;i++) { var cd=dt[i][0]; var nm=dt[i][1]; db.transaction( function(tx) { tx.executeSql( "insert into 対象 (番号,名称) values(?,?)",[cd,nm], function(tx,rs) {], fiunction(tx,er) [alert(er.message);} ); }, function(er) [alert(er.message), function() {} ); } このプログラムを実行すると(n=dt.lengthとする) ・n件の行が追加される。 ・しかしn件の行はすべて番号=dt[n-1][0]、名称=dt[n-1][1]となっている。 これはtransactionやexecuteSqlが非同期に実行されるためinsertの処理前に ループでiが増加され(従ってcdやnmも変化する)てinsertの実行時には i=n-1(従ってcd=dt[n-1]][0]、nm=dt[n-1][1])となっているためと思われる。 これを回避する方法が知りたいです。
補足
すみません、そうですよね。DBを担当してもらっている人から、現状をもらいます。
お礼
丁寧に考えていただき大変ありがとうございます。 DBの担当の人に伝えて実行してみます。 ありがとうございました。