Angular 2(ionic)SQLite一次插入数千个项目

时间:2017-12-14 12:57:59

标签: angular sqlite ionic-framework ionic2

我即将完成APP的创建,该API使用来自REST API的数据。 此应用程序与CLIENTS,ORDERS和PRODUCTS一起使用,从REST API中将它们插入到本地数据库(SQLite)中。

我需要知道存储数组中数据的有效方法是什么? 也就是说,第一次,它在阵列阵列中带来了48,000个客户端。 问题是,当您通过ITEM插入ITEM时,应用程序会被标记,或者需要很长时间才能完成。

我需要知道最有效的方法是什么。

我只是第一次",因为基于最高等级,下一次同步,我从那时开始做(并且它只带来更新的或新的)。 / p>

查询是:

'INSERT OR REPLACE INTO orders (id, C_IDPEDIDO, N_NROPEDIDO, C_CLIENTE, N_NROAUTORIZACION, FH_AUTORIZACION, FH_BAJA, C_IDFACTNOTA, N_ESTADO, X_OBSERVACION, FH_INCORPORACION, ORA_ROWSCN, state, error) VALUES ((SELECT id FROM orders WHERE C_IDPEDIDO=?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);

但是,正如我所提到的,当逐个插入时,或者它被标记或需要很多。

当返回" promises"时,我会等待他们(结束)" Observable.ForkJoin"当我完成所有时,我完成了同步

在这里,我将浏览来自网络服务的客户"客户:[]"

代码是:

let promises = [];
for(let key = 0; key < clients.length; key++) {
    // Insertamos el cliente.
    promises.push(this.SQLite_query('INSERT OR REPLACE INTO clients (id, C_CLIENTE, X_APELLIDOCLI, X_NOMBRES, X_DOMICCLI, X_LOCALIDAD, X_PROVINCIA, X_NROCUIT, X_CONDICIONIMP, ORA_ROWSCN) VALUES ((SELECT id FROM clients WHERE C_CLIENTE=?), ?, ?, ?, ?, ?, ?, ?, ?, ?)', [clients[key]['C_CLIENTE'], clients[key]['C_CLIENTE'], clients[key]['X_APELLIDOCLI'], clients[key]['X_NOMBRES'], clients[key]['X_DOMICCLI'], clients[key]['X_LOCALIDAD'], clients[key]['X_PROVINCIA'], clients[key]['X_NROCUIT'], clients[key]['X_CONDICIONIMP'], clients[key]['ORA_ROWSCN']]).then((data) => {
        // "{"rows":{"length":0},"rowsAffected":1,"insertId":1}
        if(data['rowsAffected']) {
            // Si se insertó.
            ret['inserted'].push(clients[key]['C_CLIENTE']);
        } else {
            // Si no se insertó, lo agregamos a los existentes.
            ret['existents'].push(clients[key]['C_CLIENTE']);   
        }
    }, (error) => {
        // Si hubo un error, lo agregamos a errores.
        ret['error'].push(clients[key]['C_CLIENTE']);
    }));
}
Observable.forkJoin(promises).subscribe((data) => {
    // When all the promises are over, we return the data.
    resolve(ret)
});

拜托,我需要能够解决这个问题,因为我节省了时间。

我陷入了那个我唯一缺乏能够完成它的部分。

当然,非常感谢大家!

1 个答案:

答案 0 :(得分:0)

请查看cordova-sqlite-porter,特别是JSON import optimisations上的部分。

我创建它是为了便于从SQLite DB中导入/导出数据,但除了优化从JSON结构导入大量记录外。

通过使用UNION SELECT方法described here,我能够将导入速度提高100倍。

您可以直接通过importJsonToDb()使用该插件。

或者使用批处理INSERT的relevant bit of code来创建自己的实现:

// Default maximum number of statements to use for batch inserts for bulk importing data via JSON.
var DEFAULT_BATCH_INSERT_SIZE = 250;

// Statement separator
var separator = ";\n";

var mainSql = "";
var batchInsertSize = opts.batchInsertSize ? opts.batchInsertSize : DEFAULT_BATCH_INSERT_SIZE;

if(json.data.inserts){
    for(var tableName in json.data.inserts){
        var _count = 0;
        for(var i=0; i<json.data.inserts[tableName].length; i++){
            if(_count === batchInsertSize){
                mainSql += separator;
                _count = 0;
            }

            var _row = json.data.inserts[tableName][i];
            var _fields = [];
            var _values = [];
            for(var col in _row){
                _fields.push(col);
                _values.push(sanitiseForSql(_row[col]));
            }

            if(_count === 0){
                mainSql += "INSERT OR REPLACE INTO " + sqlEscape(tableName) + " SELECT";
                for(var j = 0; j < _fields.length; j++){
                    if(typeof _values[j] === "undefined" || _values[j] === null || _values[j].toLowerCase() == 'null'){
                        mainSql += " NULL AS '" + _fields[j] + "'";
                    }else{
                        mainSql += " '" + _values[j] + "' AS '" + _fields[j] + "'";
                    }
                    if(j < _fields.length-1){
                        mainSql += ",";
                    }
                }
            }else{
                mainSql += " UNION SELECT ";
                for(var j = 0; j < _values.length; j++){
                    if(typeof _values[j] === "undefined" || _values[j] === null || _values[j].toLowerCase() == 'null'){
                        mainSql += " NULL";
                    }else{
                        mainSql += " '" + _values[j] + "'";
                    }
                    if(j < _values.length-1){
                        mainSql += ",";
                    }
                }
            }
            _count++;
        }
        mainSql += separator;
    }
}

/**
 * Sanitises a value for insertion into a SQL statement.
 * Replace occurrences of 1 single quote with 2 single quotes to SQL-escape them.
 * @param {string} value - unsanitised value
 * @returns {string} sanitised value
 */
function sanitiseForSql(value){
    if (value === null || value === undefined) { return null; }
    return (value+"").replace(/'/g,"''");
}

/**
 * Escapes the given value if it contains special characters by wrapping it with back-ticks: value => `value`.
 * @param {string} value - unescaped value
 * @return {string} escaped value
 */
function sqlEscape(value){
    if(value.match(/[_-]+/)){
        value = '`' + value + '`';
    }
    return value;
}