2013-10-22 147 views
0

我試圖創建一個NodeJS應用程序來提取SQL記錄並將它們插入到MongoDB中。我感興趣的表格有些大(100萬+記錄)。對於小數據集(< 200,000),我的應用工作得很好,但是對整個桌面運行開始消耗RAM並使服務器爬行。NodeJS操作順序

看起來Node正在運行我的「for」循環,爲每個SQL sub select分支進程,然後運行MongoDB更新。

我從來沒有看到「Mongo Connected!」直到最後一個「獲得對活動的響應#」寫入屏幕。

#!/var/node/bin/node 
var odbc = require("odbc"); 
var db = new odbc.Database(); 

var MongoClient = require('mongodb').MongoClient; 
var format = require('util').format; 

db.open("DSN=<DSN>;SERVER=<SERVER>;DATABASE=<DB>;UID=<UID>;PWD=<PWD>", function (err) { 
    if(err) throw err; 
    console.log("SQL Connected!"); 

     var sqlstr = "SELECT TOP 1000 * FROM tbl_A NOLOCK"; 
     console.log("Executing '" + sqlstr + "' against SQL Server"); 

     db.query(sqlstr, function (sql1err, rows, moreResults) { 
     if (sql1err) throw sql1err; 

     for (var i = 0; i < rows.length; i++) { 
      InsertActivity(db, rows[i], i, rows.length, function() {}); 
     } 
     }); 
}); 

function InsertActivity(sql, activity, cur, total, callback) { 
    console.log("Getting Responses for Activity #" + activity.ActivityID); 
    var rsql = "SELECT * FROM tbl_Responses NOLOCK WHERE ActivityID = " + activity.ActivityID; 
    sql.query(rsql, function (sqlerr, rows, moreResults) { 
     if (sqlerr) console.log(sqlerr); 
     activity.resonses = rows; 

     MongoClient.connect('mongodb://localhost:27017/m', function (merr, mdb) { 
     console.log("Mongo Connected!"); 
     mdb.collection("activity").insert(activity, function() { 
      console.log("Inserted Activity #" + activity.ActivityID + " inserted into Mongo"); 
      mdb.close(function() { console.log("Mongo Disconnected!"); }); 
      callback(); 
     }); 
     }); 

     if (cur == total - 1) sql.close(function() { console.log("SQL Disconnected!"); }); 
    }); 

    console.log(rsql); 
} 

回答

0

你需要的是不幸的是一個無證的函數(我會解決這個問題)。函數是db.queryResult,它返回結果對象,允許您單獨獲取行。這將避免將整個結果集緩衝到內存中。

https://github.com/wankdanker/node-odbc/blob/master/test/test-query-select-fetch.js

var db = require('odbc')(); 

db.open(connectionString, function (err) { 
    db.queryResult('select * from tbl_A NOLOCK', function (err, result) { 
     fetchMore(); 

     function fetchMore() { 
      result.fetch(function (err, data) { 
       if (!data) { 
        //we're all done, clean up 
       } 

       doStuffWithData(data, function (err) { 
        fetchMore(); 
       }); 
      }); 
     } 
    }); 
}); 

function doStuffWithData(data, cb) { 
    //do stuff 
    cb(null); 
}