2014-08-28 19 views
6

Tôi đang sử dụng các lời nhắc node-mysql, node-js và Q.Cập nhật nhiều hàng với nút-mysql, NodeJS và Q

Tôi đã cập nhật thành công, xóa và chèn các hàng đơn bằng cách sử dụng ở trên. Cũng như chèn nhiều hàng trong một câu lệnh trong trường hợp thử nghiệm của tôi.

Tuy nhiên, tôi cần phải cập nhật nhiều hàng với các giá trị khác nhau (chế độ hàng loạt) trong một truy vấn đơn lẻ hoặc trong vòng lặp for.

Thông tin về cách sử dụng câu lệnh đã chuẩn bị trong mysql2 (rất cần cải thiện trên nút-mysql) rất thưa thớt và không có ví dụ, mặc dù đó phải là lựa chọn tự nhiên, cùng với lời hứa sẽ bù cho nút-js không đồng bộ Thiên nhiên.

Ngoài ra, tôi đã sử dụng thành công defered.makeNodeResolver() trong các trường hợp thử nghiệm khác nhau.

Tôi đang cố cập nhật nhiều hàng trong một truy vấn có mệnh đề where và điều kiện thay đổi.

Tính năng này hoạt động khi tôi cập nhật một hàng. Tuy nhiên, khi tôi cố gắng cập nhật nhiều hàng với một truy vấn, các bản ghi không được cập nhật.

Tôi sẵn sàng chuyển sang sử dụng vòng lặp for để thực hiện nhiều cập nhật và sau đó tổng hợp kết quả và gửi lại từ máy chủ cho máy khách, đây sẽ là lựa chọn ưu tiên thứ hai của tôi. Và tôi không hiểu tại sao nó không nên được thực hiện theo cách đó nếu không có quá nhiều hit. Nhưng tôi đã không tìm thấy bất kỳ ví dụ để làm điều đó theo cách đó.

var values = [ 
    { users: "tom", id: 101 }, 
    { users: "george", id: 102 } 
    ]; 

    // var params = [values.users, values.id ]; 

    var sql = 'UPDATE tabletest SET users = ? WHERE id = ?;'; 


    connection.query(sql, [{users: values[0].users}, {id: values[0].id }], defered.makeNodeResolver()); 

Mã được hiển thị ở trên không thực sự cập nhật nhiều hàng. Tôi tưởng tượng có lỗi trong cú pháp của tôi.

Nhưng dù sao, cách tiếp cận tốt nhất để giải quyết vấn đề này trong trường hợp cụ thể này là gì? Các câu lệnh đã chuẩn bị, các truy vấn lặp lại trong vòng lặp for, hoặc các thủ tục lưu sẵn?

+1

Bạn đã thử sử dụng '[giá trị [0] .users, values ​​[0] .id]' làm đối số thứ hai cho truy vấn '()'? – mscdex

+0

Bạn đã chính xác. Tôi đã gặp lỗi cú pháp. Cảm ơn. Tôi đã thay đổi thành: var sql = 'UPDATE tabletest SET? Ở ĐÂU ?;'; và var query = connection.query (sql, [{users: values ​​[0] .users}, {id: values ​​[0].id}], defered.makeNodeResolver()); nhưng nó vẫn chỉ cập nhật một hàng chứ không phải cả hai. Không phải là nó phải lặp qua các đối tượng giá trị? –

+0

Tôi không chắc liệu nó có hoạt động cho UPDATE hay không, nhưng nó có thể hoạt động cho INSERT. – mscdex

Trả lời

0

Tôi không nghĩ rằng bạn có thể (ít nhất là dễ dàng/hiệu quả) cập nhật nhiều hàng theo cách bạn đang cố gắng. Bạn về cơ bản sẽ phải lặp qua số values của bạn và thực hiện một CẬP NHẬT cho từng đối tượng.

0

đoạn mã này được lấy từ vcl.js cho node.js, nó được viết bằng bản ghi và cung cấp nhiều bản cập nhật, xóa, inseer statment trong một giao dịch duy nhất.

export class SQLStatment { 
    sql: string; 
    params: Object 
} 

var dbError: string; 
var execCount: number = 0; 
function DBexecuteBatchMYSQLSingle(connection: any, SQLStatmentArray: Array<SQLStatment>, index: number, callback:() => void) { 
    execCount++; 
    connection.query(SQLStatmentArray[index].sql, SQLStatmentArray[index].params, function (err, rows, fields) { 
     if (err) dbError = err; 
     if (index + 1 == SQLStatmentArray.length) callback(); 
     else { 
      if (!dbError) { 
       DBexecuteBatchMYSQLSingle(connection, SQLStatmentArray, index + 1, function() { 
        if (index == 0) callback(); 
       }); 
      } 
     } 
    }); 
} 

function DBBatchUpdateMYSQL(SQLStatmentArray: Array<SQLStatment>, callback?: (err) => void) { 
    var mysql = require('mysql'); 
    var connection = mysql.createConnection({ 
     host: "host",user: "user",database: "db", 
     port: 1022, password: "pass"}); 
    dbError = null; 
    execCount = 0; 
    connection.beginTransaction(function (err) { 
     if (err && callback) callback("Database error:" + err); 
     else { 
      DBexecuteBatchMYSQLSingle(connection, SQLStatmentArray, 0,() => { 
       if (dbError) { 
        connection.rollback(function() { 
         if (callback) callback("Database error:" + dbError); 
        }); 
       } else { 
        connection.commit(function (err) { 
         if (callback) callback(null); 
        }) 
       } 
      }); 
     } 
    }); 
} 
+0

cuộc gọi đệ quy sẽ hoạt động. Nhưng, nếu đối phó với 10K hàng để cập nhật/chèn, nó có thể đạt đến "Maxium callback stack" vấn đề. – huangchang

4

Bạn có thể làm theo cách này:

var values = [ 
    { users: "tom", id: 101 }, 
    { users: "george", id: 102 } 
]; 
var queries = ''; 

values.forEach(function (item) { 
    queries += mysql.format("UPDATE tabletest SET users = ? WHERE id = ?; ", item); 
}); 

connection.query(queries, defered.makeNodeResolver()); 

Để sử dụng nhiều câu lệnh tính năng mà bạn phải kích hoạt nó cho kết nối của bạn:

var connection = mysql.createConnection({ 
    ... 
    multipleStatements: true, 
}); 
+0

Nhưng tác giả cho rằng tính năng câu lệnh mulitple là EXPERIMENTAL! Tôi chưa thấy bất kỳ phản hồi nào về bản ghi 10K cập nhật/chèn theo cách này. – huangchang

+1

Có bất kỳ sự phát triển nào đối với câu trả lời này không? Tôi đang tìm kiếm để làm một cái gì đó tương tự vào ngày mai và đang dự tính kết nối một truy vấn với nhau cũng có. –

0

Bạn nên có lẽ sau cách

UPDATE DB.table 
SET table.row = newValue WHERE table.someColumn in ('columnVal1', 'columnVal2'); 

ví dụ

UPDATE DB.Students 
SET result = "pass" WHERE rollNo in (21, 34, 50); 
+0

OP đang nói về việc cập nhật từ NodeJS – Mahesh

Các vấn đề liên quan