Pytanie Jak zrobić luzem insert w mySQL przy użyciu node.js


W jaki sposób można zrobić luzem wstawić do mySQL, jeśli używasz czegoś podobnego https://github.com/felixge/node-mysql


76
2018-01-17 18:33


pochodzenie


jaki masz problem? Czy możesz zrobić to w taki sam sposób, jak przy użyciu jednego polecenia sql? Po prostu rozpocznij następne polecenie po zakończeniu poprzedniego, dopóki nie wstawisz wszystkich danych. - Andrey Sidorov
Miałem wrażenie, że wkładki BULK są szybsze niż wiele pojedynczych wkładek. - crickeys
na poziomie drutu są takie same. Nie ma "bulk insert" w protokole mysql - Andrey Sidorov
w mySQL jest wiele insertów, wystarczy użyć słowa kluczowego VALUES. dev.mysql.com/doc/refman/5.5/en/insert.html Instrukcje INSERT, które używają składni VALUES, mogą wstawiać wiele wierszy. Aby to zrobić, dołącz wiele list wartości kolumn, każda zamknięta w nawiasach i oddzielona przecinkami. Przykład: INSERT INTO tbl_name (a, b, c) VALUES (1,2,3), (4,5,6), (7,8,9); - crickeys


Odpowiedzi:


Wkładki masowe są możliwe przy użyciu zagnieżdżonej tablicy, zobacz strona github

Macierze zagnieżdżone są przekształcane w zgrupowane listy (w przypadku insertów zbiorczych), np.    [['a', 'b'], ['c', 'd']] przemienia się w ('a', 'b'), ('c', 'd')

Wystarczy wstawić zagnieżdżoną tablicę elementów.

Przykład podano w tutaj

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();
});

Uwaga: values jest tablicą tablic zawijanych w tablicę

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

174
2018-01-10 13:44



Czy zapewnia to taką samą ochronę jak działanie conn.execute() używać przygotowanych wyciągów? Jeśli nie, czy możliwe jest wykorzystanie przygotowanych wyciągów podczas wykonywania wstawek? Dzięki. - Vigs
Tak, wartości są chronione tą metodą. Myślę, że jest to ten sam mechanizm co gotowe instrukcje, które również wewnętrznie używa connection.escape (). - Ragnar123
To mnie myli. Dlaczego tablica musi być [[["a", "b"], ["c", "d ']]] a nie [[" a "," b "], [" c "," d "]] jak mówi dokumentacja? - Victorio Berra
Victorio Berra, ponieważ najbardziej zewnętrzna tablica jest pasująca do znaków zapytania w ogólnym słowie, a nie tylko we wstawce. Na przykład, jeśli miałbyś dwa symbole zastępcze ze znakiem zapytania, miałbyś [param1, param2]. Powiedz "AKTUALIZUJ UŻYTKOWNIKÓW? WHERE ID =?", [Kolumny, ID] Tak więc kolumny zostaną rozszerzone do pierwszego znaku zapytania i ID do drugiego. - Selay
Niestety ta odpowiedź nie działa dla mnie. Dosłownie skopiowałem twoją odpowiedź, ale bez powodzenia. Zadałem kolejne pytanie stackoverflow.com/questions/41170849/... - Ivan Pandžić


Nie mogę jeszcze dodać komentarza, więc prześlę odpowiedź.

Odpowiedź @ Ragnar123 jest poprawna, ale widzę wiele osób w komentarzach mówiących, że to nie działa. Miałem ten sam problem i wydaje mi się, że musisz owinąć tablicę w []

więc

 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]
      ];

musi zostać przekazany jak [pars] w metodę.

Mam nadzieję że to pomoże.


9
2018-05-16 05:27



Tak, z jakiegoś powodu musi to być tablica, tablica tablic ... - Joe


Wszystkie rekwizyty do Ragnar123 za odpowiedź.

Chciałem go rozwinąć po pytaniu Josh Haringtona, aby porozmawiać o wstawionych identyfikatorach.

Będą sekwencyjne. Zobacz tę odpowiedź: Czy wielowierszowa wkładka MySQL pobiera sekwencyjne identyfikatory autoinkrementacji?

Dlatego możesz to zrobić (zauważ, co zrobiłem z wynikiem.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);
  });

(Wyciągnąłem wartości z tablicy obiektów, które nazwałem persistentObjects.)

Mam nadzieję że to pomoże.


5
2017-12-29 02:24



czy mamy gwarancję, że w przypadku jednoczesnych wstawek, stan wyścigu nie będzie mieszał identyfikatorów insertów? - Purefan
@Purefan Według moich testów tak, jednak kto wie, czy to się kiedykolwiek zmieni. - thewormsterror
Zauważ, że zadziała to tylko, jeśli rozmiar kroku auto_increment ma oryginalną wartość 1. Zobacz dev.mysql.com/doc/refman/5.7/en/... - luksch


Jeśli potrzebujemy tutaj, to jak rozwiązaliśmy wstawienie tablicy

prośba jest od listonosza (przyjrzysz się "gościom")

 {
  "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]
}

I jak pisaliśmy scenariusz

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





Szukałem odpowiedzi na zbiorcze wstawianie obiektów.

Odpowiedź Ragnar123 doprowadziła mnie do wykonania tej funkcji:

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);
});

Mam nadzieję, że to pomoże!


3
2017-08-03 22:41





Gdyby RagnarOdpowiedź nie działa dla ciebie. Oto prawdopodobnie dlaczego (na podstawie mojego doświadczenia) -

  1. Nie korzystałem node-mysql pakiet jak pokazano mój Ragnar. Używałem mysql pakiet. Są inne (jeśli nie zauważyłeś - tak jak ja). Ale nie jestem pewien, czy ma to coś wspólnego z ? nie działa, ponieważ wydawało się, że działa dla wielu osób korzystających z mysql pakiet.

  2. Spróbuj użyć zmiennej zamiast ?

Następujące pracował dla mnie -

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();
});

Mam nadzieję, że to pomaga komuś.


1
2018-02-08 00:31



Myślę, że możesz zapomnieć o umieszczeniu wartości [] na wartości. To też mi się przydarzyło. Powinien to być: conn.query (sql, [values], function () {}) Zamiast: conn.query (sql, values, function () {}) Mimo to zmienna value jest tablicą, ale nadal mamy opakować za pomocą [] - Anh Nguyen


Miałem podobny problem. Właśnie wstawiał jeden z listy tablic. Działało po wprowadzeniu poniższych zmian.

  1. Przeszedł [parametry] do metody zapytania.
  2. Zmieniono zapytanie z insert (a, b) na wartości table1 (?) ==> insert (a, b) na wartości table1? . to znaczy. Usunięto parantezę wokół znaku zapytania.

Mam nadzieję że to pomoże. Używam mysql npm.


0
2018-03-06 16:11