Câu hỏi Làm cách nào để chèn hàng loạt vào mySQL bằng cách sử dụng node.js


Làm thế nào sẽ làm một số lượng lớn chèn vào mySQL nếu sử dụng một cái gì đó như https://github.com/felixge/node-mysql


76
2018-01-17 18:33


gốc


vấn đề của bạn là gì? Bạn có thể làm điều đó theo cách tương tự như với một lệnh sql? Chỉ cần bắt đầu lệnh tiếp theo khi đã hoàn tất trước đó cho đến khi bạn chèn tất cả dữ liệu. - Andrey Sidorov
Tôi đã ấn tượng rằng BULK Inserts nhanh hơn nhiều lần chèn đơn. - crickeys
trên cấp dây chúng giống nhau. Không có 'chèn hàng loạt' trong giao thức mysql - Andrey Sidorov
có chèn nhiều trong mySQL, bạn chỉ cần sử dụng từ khóa VALUES. dev.mysql.com/doc/refman/5.5/en/insert.html Các câu lệnh INSERT sử dụng cú pháp VALUES có thể chèn nhiều hàng. Để thực hiện việc này, hãy bao gồm nhiều danh sách giá trị cột, mỗi danh sách được đặt trong dấu ngoặc đơn và được phân tách bằng dấu phẩy. Ví dụ: INSERT INTO tbl_name (a, b, c) GIÁ TRỊ (1,2,3), (4,5,6), (7,8,9); - crickeys


Các câu trả lời:


Có thể chèn hàng loạt bằng cách sử dụng mảng lồng nhau, xem trang github

Các mảng lồng nhau được chuyển thành các danh sách được nhóm (để chèn số lượng lớn), ví dụ:    [['a', 'b'], ['c', 'd']] trở thành ('a', 'b'), ('c', 'd')

Bạn chỉ cần chèn một mảng lồng nhau của các phần tử.

Một ví dụ được đưa ra đây

var mysql = require('node-mysql');
var conn = mysql.createConnection({
    ...
});

var sql = "INSERT INTO Test (name, email, n) VALUES ?";
var values = [
    ['demian', 'demian@gmail.com', 1],
    ['john', 'john@gmail.com', 2],
    ['mark', 'mark@gmail.com', 3],
    ['pete', 'pete@gmail.com', 4]
];
conn.query(sql, [values], function(err) {
    if (err) throw err;
    conn.end();
});

Chú thích: values là một mảng các mảng được bao bọc trong một mảng

[ [ [...], [...], [...] ] ]

174
2018-01-10 13:44



Điều này có cung cấp sự bảo vệ giống như thực hiện conn.execute() sử dụng báo cáo đã chuẩn bị? Nếu không, liệu có thể sử dụng các câu lệnh chuẩn bị khi thực hiện việc chèn không? Cảm ơn. - Vigs
Có, các giá trị được thoát bằng phương thức này. Tôi nghĩ rằng đó là cơ chế giống như các câu lệnh chuẩn bị, cũng sử dụng connection.escape () trong nội bộ. - Ragnar123
Điều này gây nhầm lẫn cho tôi. Tại sao mảng phải là [[['a', 'b'], ['c', 'd']]] và không phải [['a', 'b'], ['c', 'd ']] như tài liệu nói? - Victorio Berra
Victorio Berra, đó là bởi vì mảng ngoài cùng là một trong những dấu hỏi phù hợp trong tuyên bố nói chung, không chỉ trong chèn. Ví dụ: nếu bạn có hai dấu vị trí dấu hỏi, thì bạn sẽ có [param1, param2]. Nói "UPDATE người dùng? WHERE ID =?", [Cột, ID] Vì vậy, các cột sẽ được mở rộng đến dấu hỏi đầu tiên và ID thành dấu thứ hai. - Selay
Thật không may câu trả lời này không làm việc cho tôi. Tôi theo nghĩa đen đã sao chép câu trả lời của bạn nhưng không thành công. Tôi đã đăng một câu hỏi khác stackoverflow.com/questions/41170849/… - Ivan Pandžić


Tôi chưa thể nhận xét, do đó, sẽ gửi câu trả lời.

@ Ragnar123 câu trả lời là chính xác, nhưng tôi thấy rất nhiều người trong các ý kiến ​​nói rằng nó không hoạt động. Tôi đã có cùng một vấn đề và nó có vẻ như bạn cần phải bọc mảng của bạn trong []

vì thế

 var pars = [
        [99, "1984-11-20", 1.1, 2.2, 200], 
        [98, "1984-11-20", 1.1, 2.2, 200], 
        [97, "1984-11-20", 1.1, 2.2, 200]
      ];

cần phải được thông qua như [pars] vào phương pháp.

Hi vọng điêu nay co ich.


9
2018-05-16 05:27



Vâng, vì lý do nào đó nó cần phải là một mảng, của một mảng các mảng ... - Joe


Tất cả các đạo cụ cho Ragnar123 cho câu trả lời của mình.

Tôi chỉ muốn mở rộng nó sau câu hỏi của Josh Harington để nói về các ID được chèn vào.

Đây sẽ là tuần tự. Xem câu trả lời này: Có một ID tự động chèn nhiều dòng liên tiếp của MySQL không?

Do đó bạn chỉ có thể làm điều này (thông báo những gì tôi đã làm với result.insertId):

  var statement = 'INSERT INTO ?? (' + sKeys.join() + ') VALUES ?';
  var insertStatement = [tableName, values];
  var sql = db.connection.format(statement, insertStatement);
  db.connection.query(sql, function(err, result) {
    if (err) {
      return clb(err);
    }
    var rowIds = [];
    for (var i = result.insertId; i < result.insertId + result.affectedRows; i++) {
      rowIds.push(i);
    }
    for (var i in persistentObjects) {
      var persistentObject = persistentObjects[i];
      persistentObject[persistentObject.idAttributeName()] = rowIds[i];
    }
    clb(null, persistentObjects);
  });

(Tôi đã kéo các giá trị từ một mảng các đối tượng mà tôi gọi là persistentObjects.)

Hi vọng điêu nay co ich.


5
2017-12-29 02:24



chúng tôi có đảm bảo rằng trong trường hợp chèn đồng thời điều kiện cuộc đua sẽ không trộn các id chèn? - Purefan
@Purefan Theo thử nghiệm của tôi có, tuy nhiên ai biết nếu điều này sẽ bao giờ thay đổi. - thewormsterror
Lưu ý rằng điều này sẽ chỉ hoạt động nếu kích thước bước auto_increment có giá trị ban đầu là 1. Xem dev.mysql.com/doc/refman/5.7/en/… - luksch


Trong trường hợp cần thiết ở đây là cách chúng ta giải quyết chèn mảng

yêu cầu là từ người đưa thư (Bạn sẽ nhìn vào "khách")

 {
  "author_id" : 3,
  "name" : "World War II",
  "date" : "01 09 1939", 
  "time" : "16 : 22",
  "location" : "39.9333635/32.8597419",
  "guests" : [2, 3, 1337, 1942, 1453]
}

Và cách chúng tôi viết kịch bản

var express = require('express');
var utils = require('./custom_utils.js');

module.exports = function(database){
    var router = express.Router();

    router.post('/', function(req, res, next) {
        database.query('INSERT INTO activity (author_id, name, date, time, location) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE name = VALUES(name), date = VALUES(date), time = VALUES(time), location = VALUES(location)', 
                [req.body.author_id, req.body.name, req.body.date, req.body.time, req.body.location], function(err, results, fields){
            if(err){
                console.log(err);
                res.json({ status: utils.respondMSG.DB_ERROR });
            }
            else {
                var act_id = results.insertId;
                database.query('INSERT INTO act_guest (user_id, activity_id, status) VALUES ? ON DUPLICATE KEY UPDATE status = VALUES(status)', 
                        [Array.from(req.body.guests).map(function(g){ return [g, act_id, 0]; })], function(err, results, fields){
                    if(err){
                        console.log(err);
                        res.json({ status: utils.respondMSG.DB_ERROR });
                    }
                    else {
                        res.json({ 
                            status: utils.respondMSG.SUCCEED,
                            data: {
                                activity_id : act_id
                            }
                        });
                    }
                });
            }
        });
    });
    return router;
};

3
2018-02-22 20:38





Tôi đang tìm kiếm câu trả lời cho các đối tượng chèn số lượng lớn.

Câu trả lời của Ragnar123 đã dẫn tôi đến việc thực hiện chức năng này:

function bulkInsert(connection, table, objectArray, callback) {
  let keys = Object.keys(objectArray[0]);
  let values = objectArray.map( obj => keys.map( key => obj[key]));
  let sql = 'INSERT INTO ' + table + ' (' + keys.join(',') + ') VALUES ?';
  connection.query(sql, [values], function (error, results, fields) {
    if (error) callback(error);
    callback(null, results);
  });
}

bulkInsert(connection, 'my_table_of_objects', objectArray, (error, response) => {
  if (error) res.send(error);
  res.json(response);
});

Hy vọng nó giúp!


3
2017-08-03 22:41





Nếu RagnarCâu trả lời của bạn không phù hợp với bạn. Đây có lẽ là lý do tại sao (dựa trên kinh nghiệm của tôi) -

  1. Tôi đã không sử dụng node-mysql gói như được hiển thị của tôi Ragnar. tôi đang sử dụng mysql gói. Chúng khác nhau (nếu bạn không chú ý - giống như tôi). Nhưng tôi không chắc liệu nó có liên quan gì đến ? không hoạt động, vì nó dường như hoạt động với nhiều người sử dụng mysql gói.

  2. Thử sử dụng biến thay vì ?

Sau đây làm việc cho tôi -

var mysql = require('node-mysql');
var conn = mysql.createConnection({
    ...
});

var sql = "INSERT INTO Test (name, email, n) VALUES :params";
var values = [
    ['demian', 'demian@gmail.com', 1],
    ['john', 'john@gmail.com', 2],
    ['mark', 'mark@gmail.com', 3],
    ['pete', 'pete@gmail.com', 4]
];
conn.query(sql, { params: values}, function(err) {
    if (err) throw err;
    conn.end();
});

Hy vọng điều này sẽ giúp một ai đó.


1
2018-02-08 00:31



Tôi nghĩ bạn có thể quên đặt [] thành giá trị. Nó cũng xảy ra với tôi. Nó phải là: conn.query (sql, [values], function () {}) Thay vì: conn.query (sql, values, function () {}) Mặc dù biến giá trị là một mảng, nhưng chúng ta vẫn có quấn nó với [] - Anh Nguyen


Tôi đã gặp vấn đề tương tự. Nó chỉ là chèn một từ danh sách các mảng. Nó hoạt động sau khi thực hiện các thay đổi bên dưới.

  1. Đã chuyển [params] cho phương thức truy vấn.
  2. Đã thay đổi truy vấn từ chèn (a, b) thành các giá trị table1 (?) ==> chèn (a, b) vào các giá trị table1? . I E. Loại bỏ dấu ngoặc xung quanh dấu chấm hỏi.

Hi vọng điêu nay co ich. Tôi đang sử dụng mysql npm.


0
2018-03-06 16:11