質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.49%

csvのデータ数とDBのデータ数が合わない

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,214

k-ichigo

score 5

前提・実現したいこと

monacaでスマホアプリの開発を行っています。
使用しているのはjavascript,AngularjS,onsen ui,SQLiteです。
その中で、sqliteにデータを書き込んで、参照を行おうとしています。

csvからデータを書き込んで、リストで表示して選択などを行うことは出来ているのですが、
元々のcsvのデータ数が2万件程なのに対し、
"select" で参照した時の[object SQLresultSet]の件数や、"select count(*)" で行数を検索すると、1000行程しか入っていなかったりします。
csvを読み取った時の配列の数は元々のデータ数と一致しています。

全件読んで、その中から特定のものを選んでリストに表示して選択出来る様にしたいのですが、
どこか間違っているのでしょうか。

該当のソースコード

var webdb = {};
    webdb.db = null;
    // File APIに対応しているか確認

    // Databaseオープン
    webdb.open = function() {
        var dbSize = 5 * 1024 * 1024;
        webdb.db = window.openDatabase('sample', '1.0', 'sampleDB', dbSize);
    };
    // データ作成
    webdb.insert = function(name, d,eigc,kana, success, error) {
        webdb.db.transaction(function(tx){
            tx.executeSql('INSERT INTO SAMPLE(CD,NAME, EIGC, KANA) VALUES (?,?,?,?)', [name, d,eigc,kana], insertSuccess, dberror);
        });
    };
if(window.File) {
            var select = document.getElementById('select');

            // ファイルが選択されたとき
            select.addEventListener('change', function(e) {
                //DBを一度削除
                delData();
                // 選択されたファイルの情報を取得
                var fileData = e.target.files[0];
                var e_all = document.createElement("innerHTML");

                var reader = new FileReader();
                // ファイル読み取りに失敗したとき
                reader.onerror = function() {
                    alert('ファイル読み取りに失敗しました');
                };
                // ファイル読み取りに成功したとき
                reader.onload = function() {
                    alert('読み取りを開始します'+reader.result.split("\n").length);
                    var cnt=0;
                    // 行単位で配列にする
                    var lineArr = reader.result.split("\n");
                    // 行と列の二次元配列にする
                    var itemArr = [];
                    for (var i = 0; i < lineArr.length; i++) {
                        itemArr[i] = lineArr[i].split(",");
                    }
                    for (var i = 0; i < itemArr.length; i++) {
                        if(itemArr[i][0]!= ''){
                            writeDB(itemArr[i][0],itemArr[i][1],itemArr[i][2],itemArr[i][3]);
                        }
                    }
                    alert("完了しました");
                };
                // ファイル読み取りを実行
                reader.readAsText(fileData,'shift-jis');
            } );
        };

function writeDB(cd,name,eigc,kana){
    tokdb.insert(cd,name,eigc,kana,insertSuccess,dbError);
}
// エラー
function dbError(tx, e) {
    alert('エラー\n' + e.message);
}
// データ作成が成功
function insertSuccess(tx) {
    //alert('データを作成しました。');
}
//DBを読んでリストに書き出す部分
var app = ons.bootstrap("myApp", ["onsen"]);
    app.controller("page1Controller", ["$scope", function($scope) {
        $scope.srchtk = function(){
            $scope.tctable=[];
            var list= [];
            var sql = null;
            var wdb = window.openDatabase('sample', '1.0', 'sample', 5 * 1024 * 1024);
            wdb.transaction(function(tx){
                spl="SELECT * FROM SAMPLE ORDER BY KANA";
                tx.executeSql(spl,[],function(tx,r){
                    alert('データ数:'+r.rows.length); //1000件程度
                    for(var i = 0; i < r.rows.length; i++){
                        //配列(list)に格納
                    }
                    $scope.tctable = list;
                    $scope.$apply();
                    alert("完了しました");
                },function(){
                    console.log("error select");
                });
            });  
        };
    }]);

試したこと

var reader = new FileReader;
reader.onload = function(){
    alert(reader.result.split("\n").length;
    ...
}


上記でファイルを読んで、splitで分けた時の行数はcsvのデータ数と同じ約2万件で

var webdb={};
var webdb.db = openDatabase('sample', '1.0', 'sample', 5 * 1024 * 1024);
webdb.db.transaction(function(tx){
    var sql="SELECT * FROM SATKUI ORDER BY KANA";
    tx.executeSql(sql, [], success, error);
});
}


上記でデータベースを参照した時、[object SQLresultSet]に入っている".rows"の長さ(.length)が1000件程度だったり、200件程度だったりと、その時々で値が変わったりし、いずれも2000件を超えることはありませんでした。

補足情報(言語/FW/ツール等のバージョンなど)

より詳細な情報

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

check解決した方法

0

openDatabase('sample','1.0','sample',DBsize);のDBsize
をこれまで 5*1024*1024 としていたのですが、
15*1024*1024 に変えたところ、時間がかかりますが2万件読み込ませることが出来ました。

ご迷惑をおかけしました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

DBへの書き込みのところにバグがあると思います。

質問のコードの

                // ファイル読み取りに成功したとき
                reader.onload = function() {
                    alert('読み取りを開始します'+reader.result.split("\n").length);
                    var cnt=0;
                    // 行単位で配列にする
                    var lineArr = reader.result.split("\n");
                    // 行と列の二次元配列にする
                    var itemArr = [];
                    for (var i = 0; i < lineArr.length; i++) {
                        itemArr[i] = lineArr[i].split(",");
                    }
                    for (var i = 0; i < itemArr.length; i++) {
                        if(itemArr[i][0]!= ''){
                            writeDB(itemArr[i][0],itemArr[i][1],itemArr[i][2],itemArr[i][3]);
                        }
                    }
                    alert("完了しました");
                };


の部分は

                // ファイル読み取りに成功したとき
                reader.onload = function() {
                    alert('読み取りを開始します'+reader.result.split("\n").length);
                    var cnt=0;
                    // 行単位で配列にする
                    var lineArr = reader.result.split("\n");

                    // 行と列の二次元配列にするのではなく、「1行分のデータを列の配列にしてはDBに書き込む」を繰り返す。
                    var itemArr = []; // 列の配列
                    for (var i = 0; i < lineArr.length; i++) {
             //1行分を、列単位で配列にする
                        itemArr[] = lineArr[i].split(",");
                        if(itemArr[i][0]!= ''){ //1行分を、DBにレコードとして書き込む
                            writeDB(itemArr[i][0],itemArr[i][1],itemArr[i][2],itemArr[i][3]);
                        }
                    }
                    alert("完了しました");
                };


のような感じで、DBにレコード(csvの1行分)を書き込む操作がcsvファイルの行数 (lineArr.length)分繰り返すようになってるべきです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/01 16:23

    書いてある通りに変更したところ、結果は特に変わりませんでした。
    行っていて気付いたのですが、
    ```
    tx.executeSql(sql, [], function(tx,r){
    alert("データの長さ:"+r.rows.length);
    // ・・・
    }, error);
    ```
    として、ボタンクリックで都度DBを読み込んでいて、その際に"SQLresultset"の長さをalertで表示していたのですが、CSVを読み込ませたあと、ボタンクリックを何度か行うと、
    "データの長さ:100"、"データの長さ:250"、"データの長さ:520"のように
    徐々に増加し、"データの長さ:1040"で固定されました。
    selectで読んだ際のSQLresultsetに入るデータの上限とかが原因でしょうか?

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる