Tedious: рдЕрдиреБрд░реЛрдз рдХреЗрд╡рд▓ LoggedIn рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ, SentClientRequest рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдирд╣реАрдВ (рдХреЛрдб: 'EINVALIDSTATE')

рдХреЛ рдирд┐рд░реНрдорд┐рдд 28 рд╕рд┐рддре░ 2016  ┬╖  23рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: tediousjs/tedious

рдиреАрдЪреЗ рдореЗрд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдореИрдВ рдХрд╛рд░реНрдпреЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рдХреЛ рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рд▓реЗрдХрд┐рди рдЕрдиреБрд░реЛрдз рдХреЗрд╡рд▓ рд▓реЙрдЧ рдЗрди рд░рд╛рдЬреНрдп рдореЗрдВ рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдЙрд╕ connection.state !== connection.STATE.LOGGED_IN рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреА рдкрдбрд╝реАред рдФрд░ рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рд░реАрдб рдлрдВрдХреНрд╢рди рдореЗрдВ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рддреНрд░реБрдЯрд┐ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдХреЛ рд╡рд╛рдкрд╕ рдХрддрд╛рд░ рдореЗрдВ рд▓рдЧрд╛рдирд╛ рдкрдбрд╝рд╛ред

{ [RequestError: Requests can only be made in the LoggedIn state, not the SentClientRequest state]
  message: 'Requests can only be made in the LoggedIn state, not the SentClientRequest state',
  code: 'EINVALIDSTATE' }

рдХреНрдпрд╛ рдЗрд╕реЗ рд╣рд╛рд╕рд┐рд▓ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдмреЗрд╣рддрд░ рддрд░реАрдХрд╛ рд╣реИ? рдореИрдВрдиреЗ рджреЗрдЦрд╛ рд╣реИ рдХрд┐ рдЗрд╕реА рддрд░рд╣ рдХреЗ рдореБрджреНрджреЗ #19 рдФрд░ #355 рд╕реЗ рдкрд╣рд▓реЗ рдЙрдард╛рдП рдЧрдП рдереЗред рдХреНрдпрд╛ рдХрдиреЗрдХреНрд╢рди рдкрд░ рдПрдХрд╛рдзрд┐рдХ рдЕрдиреБрд░реЛрдз рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдЕрдиреБрд╢рдВрд╕рд┐рдд рддрд░реАрдХрд╛ рд╣реИ?

рдХреЛрдб:

var Connection = require('tedious').Connection;  
var Request = require('tedious').Request;  
var TYPES = require('tedious').TYPES;  
var async = require('async');

// Create connection to database
var config = {
        userName: 'mylogin',  
        password: 'mypassword',  
        server: 'localhost',
        options: {
            // encrypt: true, /*If you are connecting to a Microsoft Azure SQL database, you will need this*/
            database: 'testdb'
        }
    }
var connection = new Connection(config);  

// Attempt to connect and execute queries if connection goes through
connection.on('connect', function(err) {  
    if (err) {
        console.log(err);
    }  
    else    {
        console.log("Connected");

        // Execute all functions in the array serially
        async.waterfall([
            function Start(callback){
                console.log("Starting...");
                callback(null, 'Jake', 'United States');
            },
            function Insert(name, location, callback){
                console.log("Inserting into Table...");

                request = new Request("INSERT dbo.employees (name, location) OUTPUT INSERTED.id VALUES (<strong i="14">@Name</strong>, @Location);", function(err){  
                     if (err) {
                            console.log(err);
                        }  
                    }
                );  
                request.addParameter('Name', TYPES.NVarChar, name);  
                request.addParameter('Location', TYPES.NVarChar, location);  

                request.on('row', function(columns) {  
                    columns.forEach(function(column) {  
                      if (column.value === null) {  
                        console.log('NULL');  
                      } else {  
                        console.log("Employee id inserted is " + column.value);  
                      }  
                    });  
                }); 

                // Check how many rows were inserted
                request.on('doneInProc', function(rowCount, more) {  
                    console.log(rowCount + ' row(s) inserted');  
                    callback(null, 'Jared');
                });             

                connection.execSql(request);  
            },
            function Read(callback){
                // Requests can only be made in the LoggedIn state, so check for that
                if (connection.state !== connection.STATE.LOGGED_IN) {
                    // Put the request back on the dispatcher if connection is not in LoggedIn state
                    setTimeout(Read, 0, callback);
                    return;
                }

                console.log("Reading rows from the Table...");

                // Create the request to read from table
                request = new Request("SELECT * FROM dbo.employees;", function(err) {  
                    if (err) {
                        console.log(err);
                    }  
                });  

                // Output the number of rows read 
                request.on('doneInProc', function (rowCount, more, rows) {  
                    console.log(rowCount + ' row(s) returned');  
                    callback(null);
                });  

                connection.execSql(request);  
            }],
            function Complete(err, result) {
                if(err) {
                    console.log("Error:", err);
                }
                else {
                    console.log("Done!");
                }
            }
        )
    }
});

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

Google рд╕реЗ рдпрд╣рд╛рдВ рдЖрдиреЗ рд╡рд╛рд▓реЗ рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП (рдЬреИрд╕реЗ рдореИрдВрдиреЗ рдХрд┐рдпрд╛): рдердХрд╛рдК-рдХрдиреЗрдХреНрд╢рди-рдкреВрд▓ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХрд╛ рдПрдХ рд╢рд╛рдирджрд╛рд░ рддрд░реАрдХрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рд╕рдорд╡рд░реНрддреА рдореБрджреНрджреЛрдВ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП pool.acquire((err, connection) => ...) рдФрд░ connection.release() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдПрдХ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдПрдХрд╛рдзрд┐рдХ рдХрдиреЗрдХреНрд╢рди рдирд╣реАрдВ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рдкреНрд░рднрд╛рд╡реА рдврдВрдЧ рд╕реЗ рдХреНрд░рдордмрджреНрдз рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреВрд▓ рдХреЛ {min: 1, max: 1} рдХреЗ рд╕рд╛рде рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВред

рд╕рднреА 23 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдПрдХ 'рдХреЙрд▓рдмреИрдХ' рд╕рдВрдкрддреНрддрд┐ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдк рдЕрдиреБрд░реЛрдз рдкрд░ рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЕрдиреБрд░реЛрдз рдкрд░ рдПрдХ 'рдЕрдиреБрд░реЛрдз рдкреВрд░реНрдг' рдШрдЯрдирд╛ рд╣реИ, рджреЛрдиреЛрдВ рдХрд╛рдо рд▓рдЧрддреЗ рд╣реИрдВред рдФрд░ рд╡реЗ рджреЛ рдЪреАрдЬреЗрдВ рд╣реИрдВ рдЬрд┐рдирдХреА рд╣рдордиреЗ рдХреЛрд╢рд┐рд╢ рдирд╣реАрдВ рдХреА :)

рдЗрд╕ рдкрд░ рдХреБрдЫ рд╕рдлрд╛рдИ рдФрд░ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИред

рдЗрдиреНрд╣реЗрдВ рдЖрдЬрдорд╛рдПрдВ рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВред

'рдХреЙрд▓рдмреИрдХ' рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛:

  request.callback = function (err, rowCount, rows) {
      // rows is not being set but rowCount is. May be a bug.
      if (err) {
        // Error handling.
      } else {
        // Next SQL statement.
      }
  };

'рдЕрдиреБрд░реЛрдз рдкреВрд░реНрдг' рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛:

  request.on('requestCompleted', function () {
      // Next SQL statement.
  });

рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕ рдиреЛрдЯ рдХреЛ https://github.com/tediousjs/tedious/issues/61 рдореЗрдВ рдбрд╛рд▓реВрдВрдЧрд╛ рдФрд░ рдЗрд╕реЗ рдмрдВрдж рдХрд░ рджреВрдВрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╡рд╣реА рдореБрджреНрджрд╛ рд╣реИред

рдореБрджреНрджреЗ рдХреЛ рдлрд┐рд░ рд╕реЗ рдЦреЛрд▓рдирд╛ред https://github.com/tediousjs/tedious/issues/61 рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд╕рдВрдмрдВрдзрд┐рдд рд╣реИред @SaloniSonpal рджреНрд╡рд╛рд░рд╛ рдмрддрд╛рдП рдЧрдП рдореБрджреНрджреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрдВрдж рд╣реИрдВред рдЗрд╕рд▓рд┐рдП рдЯреНрд░реИрдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рдЦреЛрд▓ рд░рд╣реЗ рд╣реИрдВред

рдЗрд╕рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╕рдлрд╛рдИ рдФрд░ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдзрдиреНрдпрд╡рд╛рдж @tvrprasadред рдпреЗ рджреЛрдиреЛрдВ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рд╕рд╛рдл-рд╕реБрдерд░реЗ рд╣реИрдВред callback рджреГрд╖реНрдЯрд┐рдХреЛрдг рддреНрд░реБрдЯрд┐ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХрд╛ рд▓рд╛рдн рджреЗрддрд╛ рд╣реИред Event: 'requestCompleted' рдХреЛ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдкреНрд░рд▓реЗрдЦрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

(рдореЗрд░реЗ рдлреЛрди рд╕реЗ рднреЗрдЬ рд░рд╣реЗ рд╣реИрдВ, рд╕рдВрдХреНрд╖рд┐рдкреНрддрддрд╛ рдХреЗ рд▓рд┐рдП рдХреНрд╖рдорд╛ рдХрд░реЗрдВ)ред

рдХреЙрд▓рдмреИрдХ рдЧреБрдг рд╕реЗрдЯ рдХрд░рдирд╛ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рдкрд╛рд░рд┐рдд рдХреЙрд▓рдмреИрдХ рдХреЛ рдЕрдзрд┐рд▓реЗрдЦрд┐рдд рдХрд░ рджреЗрдЧрд╛
рдЕрдиреБрд░реЛрдз рдирд┐рд░реНрдорд╛рддрд╛ рдХреЗ рд▓рд┐рдПред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдЖрдкрдХреЛ рдХреЙрд▓рдмреИрдХ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП
рдХреЙрд▓рдмреИрдХ рдХреЗ рдЕрдВрджрд░ async рдЕрдиреБрд░реЛрдз рдирд┐рд░реНрдорд╛рддрд╛ рдХреЛ рджрд┐рдпрд╛ рдЧрдпрд╛ред рдЗрд╕ рддрд░рд╣ рдЖрдк
рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ async рдкрд░ рдЕрдЧреНрд░реЗрд╖рд┐рдд рднреА рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдЖрд╣, рдпрд╛рдж рдЖрдпрд╛ рдХрд┐ рдХреЙрд▓рдмреИрдХ рдкрд╛рд╕ рдХрд┐рдП рдЧрдП рдХреЙрд▓рдмреИрдХ рдкрд░ рд╕реЗрдЯ рд╣реИред рддреЛ рд╕рд╣реА рддрд░реАрдХрд╛ рд╣реЛрдЧрд╛:

  request = new Request(sqlQuery, function (err, rowCount, rows) {
    if (err) {
      // Error handling.
    } else {
      // Next SQL statement.
    }
  });

@arthurschreiber 'рдЕрдиреБрд░реЛрдз рдкреВрд░реНрдг' рдШрдЯрдирд╛ рдХрд╛ рдХреЛрдИ рдХрд╛рд░рдг? рдЕрдирд╛рд╡рд╢реНрдпрдХ рд▓рдЧрддрд╛ рд╣реИред рдПрдХ рдФрд░ рдЪреАрдЬ рдЬреЛ рдореИрдВрдиреЗ рдиреЛрдЯрд┐рд╕ рдХреА рд╣реИ рд╡рд╣ рд╣реИ рдХрд┐ рдХреЙрд▓рдмреИрдХ рдореЗрдВ рдкрд╛рд╕ рдХреА рдЧрдИ рдкрдВрдХреНрддрд┐рдпрд╛рдБ рдкреИрд░рд╛рдореАрдЯрд░ рд╣рдореЗрд╢рд╛ рдЦрд╛рд▓реА рд╣реЛрддреА рд╣реИрдВред рдХреНрдпрд╛ рдХреЛрдИ рдРрд╕рд╛ рдкрд░рд┐рджреГрд╢реНрдп рд╣реИ рдЬрд╣рд╛рдВ рдЙрд╕рдХреЗ рдкрд╛рд╕ рд╡реИрдз рдбреЗрдЯрд╛ рд╣реЛрдЧрд╛? рдореИрдВ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдЕрдкрдбреЗрдЯ рдХрд░реВрдВрдЧрд╛ред

рдПрдХ рдФрд░ рдЪреАрдЬ рдЬреЛ рдореИрдВрдиреЗ рдиреЛрдЯрд┐рд╕ рдХреА рд╣реИ рд╡рд╣ рд╣реИ рдХрд┐ рдХреЙрд▓рдмреИрдХ рдореЗрдВ рдкрд╛рд╕ рдХреА рдЧрдИ рдкрдВрдХреНрддрд┐рдпрд╛рдБ рдкреИрд░рд╛рдореАрдЯрд░ рд╣рдореЗрд╢рд╛ рдЦрд╛рд▓реА рд╣реЛрддреА рд╣реИрдВред рдХреНрдпрд╛ рдХреЛрдИ рдРрд╕рд╛ рдкрд░рд┐рджреГрд╢реНрдп рд╣реИ рдЬрд╣рд╛рдВ рдЙрд╕рдХреЗ рдкрд╛рд╕ рд╡реИрдз рдбреЗрдЯрд╛ рд╣реЛрдЧрд╛? рдореИрдВ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдЕрдкрдбреЗрдЯ рдХрд░реВрдВрдЧрд╛ред

rowCollectionOnRequestCompletion рд╡рд┐рдХрд▓реНрдк рд╣реИ рдЬрд┐рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рддреЗ рд╕рдордп рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕реЗ рд╡реИрд╢реНрд╡рд┐рдХ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд░реВрдк рдореЗрдВ рд░рдЦрдирд╛ рдереЛрдбрд╝рд╛ рдЕрдЬреАрдм рд╣реИ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдкреНрд░рддрд┐-рдЕрдиреБрд░реЛрдз рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдФрд░ рдЕрдзрд┐рдХ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред

рдЗрд╕рдХреЗ рдкреАрдЫреЗ рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╣реИ: рдпрджрд┐ rowCollectionOnRequestCompletion рд╡рд┐рдХрд▓реНрдк рд╕рдХреНрд╖рдо рд╣реИ рддреЛ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рд╕реНрдореГрддрд┐ рдореЗрдВ рддрдм рддрдХ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рддрдХ рдХрд┐ рд╕рдВрдмрдВрдзрд┐рдд Request рдкреВрд░рд╛ рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛ (рдФрд░ рд╡рд░реНрддрдорд╛рди рдореЗрдВ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЗрдВ Request рддрдХ рднреА рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣реИ ред рдкрд╕рдВрджреАрджрд╛ рддрд░реАрдХрд╛ рдХреЗрд╡рд▓ rows рдХреЙрд▓рдмреИрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдЖрдкрдХреЛ рд╕рднреА рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдПрдХ рд╕рд░рдгреА рдореЗрдВ рдПрдХрддреНрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЖрдк рд╕реНрд╡рдпрдВ рдРрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдпрд╣ рдЗрд╖реНрдЯрддрдо рд╣реИ, рдкреНрд░рддрд┐-рдХрдиреЗрдХреНрд╢рди рдХреЗ рдмрдЬрд╛рдп рдпрд╣ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдкреНрд░рддрд┐-рдЕрдиреБрд░реЛрдз рд╢рд╛рдпрдж рдмреЗрд╣рддрд░ рд╣реЛрдЧрд╛ - рд▓реЗрдХрд┐рди Request рдХрдиреНрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдЕрднреА рддрдХ рдХреЛрдИ рд╡рд┐рдХрд▓реНрдк рдирд╣реАрдВ рд▓реЗрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╡рд┐рдзрд┐ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдмрджрд▓рд╛ рд╣реБрдЖред

'рдЕрдиреБрд░реЛрдз рдкреВрд░реНрдг' рдШрдЯрдирд╛ рдХрд╛ рдХреЛрдИ рдХрд╛рд░рдг?

рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ - рдердХрд╛рдК рдкрд░ рдХрд╛рдо рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЗрд╕реЗ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдерд╛ред

RowCollectionOnRequestCompletion рд╕рдорд╕реНрдпрд╛ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП #459 рдЦреЛрд▓рд╛ рдЧрдпрд╛ред рдореБрдЭреЗ рдпрдХреАрди рд╣реИ рдХрд┐ рд╣рдо рдЗрд╕реЗ рдЬреЛрдбрд╝ рдФрд░ рд╕рдВрднрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ
рдкрд┐рдЫрдбрд╝реЗ рд╕рдВрдЧрдд рддрд░реАрдХреЗ рд╕реЗред

рдХреЙрд▓рдмреИрдХ рдЧреБрдг рд╕реЗрдЯ рдХрд░рдирд╛ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рдкрд╛рд░рд┐рдд рдХреЙрд▓рдмреИрдХ рдХреЛ рдЕрдзрд┐рд▓реЗрдЦрд┐рдд рдХрд░ рджреЗрдЧрд╛
рдЕрдиреБрд░реЛрдз рдирд┐рд░реНрдорд╛рддрд╛ рдХреЗ рд▓рд┐рдПред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдЖрдкрдХреЛ рдХреЙрд▓рдмреИрдХ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП
рдХреЙрд▓рдмреИрдХ рдХреЗ рдЕрдВрджрд░ async рдЕрдиреБрд░реЛрдз рдирд┐рд░реНрдорд╛рддрд╛ рдХреЛ рджрд┐рдпрд╛ рдЧрдпрд╛ред рдЗрд╕ рддрд░рд╣ рдЖрдк
рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ async рдкрд░ рдЕрдЧреНрд░реЗрд╖рд┐рдд рднреА рдХрд░ рд╕рдХрддрд╛ рд╣реИред

@arthurschreiber рдЖрдк рд╕рд╣реА рдХрд╣ рд░рд╣реЗ рд╣реИрдВред рдкрд░рд┐рдгрд╛рдореЛрдВ/рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рди рдХрд░рдиреЗ рдХрд╛ рдпрд╣ рд╕рд╣реА рддрд░реАрдХрд╛ рд╣реИред рдЬрд╛рджреВ рдХреА рддрд░рд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ :-)

Event: 'requestCompleted' . рдкрд░ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдореЗрдВ рд╕реБрдзрд╛рд░ рдХреЗ рд▓рд┐рдП #464 рдмрдирд╛рдпрд╛ рдЧрдпрд╛

Google рд╕реЗ рдпрд╣рд╛рдВ рдЖрдиреЗ рд╡рд╛рд▓реЗ рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП (рдЬреИрд╕реЗ рдореИрдВрдиреЗ рдХрд┐рдпрд╛): рдердХрд╛рдК-рдХрдиреЗрдХреНрд╢рди-рдкреВрд▓ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХрд╛ рдПрдХ рд╢рд╛рдирджрд╛рд░ рддрд░реАрдХрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рд╕рдорд╡рд░реНрддреА рдореБрджреНрджреЛрдВ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП pool.acquire((err, connection) => ...) рдФрд░ connection.release() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдПрдХ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдПрдХрд╛рдзрд┐рдХ рдХрдиреЗрдХреНрд╢рди рдирд╣реАрдВ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рдкреНрд░рднрд╛рд╡реА рдврдВрдЧ рд╕реЗ рдХреНрд░рдордмрджреНрдз рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреВрд▓ рдХреЛ {min: 1, max: 1} рдХреЗ рд╕рд╛рде рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВред

рдХреГрдкрдпрд╛ рдХреЛрдИ рднреА рд╕реБрдЭрд╛рд╡ рджреЗрдВ, рд╡рд┐рдВрдбреЛрдЬрд╝ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдореЛрдб nodejs2Sql рдХрдиреЗрдХреНрдЯрд┐рд╡рд┐рдЯреА рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИред

@wafaabbass tedious рдЕрднреА рддрдХ рд╡рд┐рдВрдбреЛрдЬрд╝ рдПрдХреАрдХреГрдд рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рд╣рдо рдЗрд╕ рдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдЖрдк рдЗрд╕реЗ #415 рдореЗрдВ рдЯреНрд░реИрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЕрд░реЗ, рд╕рдм рд▓реЛрдЧ, рдореБрдЭреЗ рдПрдХ рд╣реА рд╕рдорд╕реНрдпрд╛ рд╣реИред

рдбрд┐рдмрдЧ:

рдЕрдиреБрд░реЛрдз рдХреЗрд╡рд▓ LoggedIn рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, SentClientRequest рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдирд╣реАрдВ
(рдиреЛрдб: 5180) UnhandledPromiseRejectionWarning: рдЕрдирдЪрд╛рд╣реЗ рд╡рд╛рджрд╛ рдЕрд╕реНрд╡реАрдХреГрддрд┐ (рдЕрд╕реНрд╡реАрдХреГрддрд┐ рдЖрдИрдбреА: 1): RequestError: рдЕрдиреБрд░реЛрдз рдХреЗрд╡рд▓ LoggedIn рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ, SentClientRequest рд╕реНрдерд┐рддрд┐ рдирд╣реАрдВ
(рдиреЛрдб: 5180) [рдбреАрдИрдкреА0018] рдмрд╣рд┐рд╖реНрдХрд░рдг рдЪреЗрддрд╛рд╡рдиреА: рдмрд┐рдирд╛ рдХреНрд░рд┐рдпрд╛ рдХреЗ рд╡рд╛рджреЗ рдХреЛ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рднрд╡рд┐рд╖реНрдп рдореЗрдВ, рд╡рд╛рджрд╛ рдЕрд╕реНрд╡реАрдХрд░рдг рдЬреЛ рд╕рдВрднрд╛рд▓рд╛ рдирд╣реАрдВ рдЬрд╛рддрд╛ рд╣реИ, рдЧреИрд░-рд╢реВрдиреНрдп рдирд┐рдХрд╛рд╕ рдХреЛрдб рдХреЗ рд╕рд╛рде Node.js рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░ рджреЗрдЧрд╛ред

рдХреНрдпрд╛ рдпрд╣ рдЕрднреА рддрдХ рд╣рд▓ рд╣реЛ рдЧрдпрд╛ рд╣реИ? рдпрд╣ рдореЗрд░рд╛ рдХреЛрдб рд╣реИред

function createAsPromiseWithTransaction(callback, data, connection) {

  const transactionReady = (err) => {
    if (err) {
      return callback(err)
    }
    return callback(null)
  }

  const transactionFailed = (originalErr) =>
    (err) => {
      if (err) {
        return callback(err)
      }
      return callback(originalErr)
    }

  const willIGetArea = new Promise(
    (resolve, reject) => {
      const create = function(data, connection) {
        let areaIdInserted = null
        const request = new Request(CONSTANTS.SPNames.Area,
          (err, rowCount, rows) => err ? reject(err) : resolve(areaIdInserted))

        request.addParameter('IUser', TYPES.UniqueIdentifier, data.iUser)
        request.addParameter('ParentArea', TYPES.Int, data.parentArea)
        request.addParameter('Name', TYPES.VarChar, data.nameArea)
        request.addParameter('ShortName', TYPES.VarChar, data.shortNameArea)
        request.addParameter('Description', TYPES.VarChar, data.descriptionArea)
        request.addParameter('Gender', TYPES.Bit, data.gender)
        request.addParameter('Colour', TYPES.VarChar, data.colour)
        request.addParameter('X', TYPES.Int, data.x)
        request.addParameter('Y', TYPES.Int, data.y)
        request.addParameter('Active', TYPES.Int, data.active)

        request.on('row', function(columns) {
          areaIdInserted = columns[1].value
        });

        connection.callProcedure(request)
      }

      const transactionStarted = function(err) {
        if (err) return callback(err)
        create(data, connection)
      }

      connection.beginTransaction(transactionStarted)
    })

  const willIGetSymptom = function(areaId) {

    return new Promise(function(resolve, reject) {

      const create = function(data, connection, areaId) {
        let symptomIdInserted = null
        const request = new Request(CONSTANTS.SPNames.Symptom,
          (err, rowCount, rows) => err ? reject(err) : resolve(symptomIdInserted))

        request.addParameter('IUser', TYPES.UniqueIdentifier, data.iUser)
        request.addParameter('AreaId', TYPES.BigInt, areaId)
        request.addParameter('Code', TYPES.VarChar, data.code)
        request.addParameter('Name', TYPES.VarChar, data.nameSymptom)
        request.addParameter('ShortName', TYPES.VarChar, data.shortNameSymptom)
        request.addParameter('Description', TYPES.VarChar, data.descriptionSymptom)
        request.addParameter('Gender', TYPES.Bit, data.gender)
        request.addParameter('Active', TYPES.Bit, data.active)

        request.on('row', function(columns) {
          symptomIdInserted = columns[1].value
        });


        connection.callProcedure(request)
      }

      create(data, connection, areaId)

    })
  }

  const willIGetModifier = new Promise(function(resolve, reject) {

    const request = new Request(
      CONSTANTS.SPNames.Modifier,
      function(err, rowCount, rows) {
        if (err) {
          reject(err)
        } else {
          resolve(rowCount,rows)
        }
      })

    request.addParameter('IUser', TYPES.UniqueIdentifier, data.iUser)
    request.addParameter('Name', TYPES.VarChar, data.nameModifier)
    request.addParameter('Order', TYPES.SmallInt, data.order)
    request.addParameter('Active', TYPES.Bit, data.active)

    connection.callProcedure(request)

  })

  const runPromise = () =>
    willIGetArea
    .then( (areaId) =>
      willIGetSymptom(areaId)
      .then( (symptomId) =>
        willIGetModifier
        .then((rowCount,rows) => connection.commitTransaction(transactionReady))
        .catch((err) => connection.rollbackTransaction(transactionFailed(err)))
      )
      .catch((err) => connection.rollbackTransaction(transactionFailed(err)))
    )it 
    .catch((err) => connection.rollbackTransaction(transactionFailed(err)))

  runPromise()

}

рдЕрдЧрд░ рдореИрдВ willIGetArea рдФрд░ willIGetSymptom рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реВрдВ, рддреЛ рдпрд╣ рд╕рдм рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдореИрдВ рдЗрд╕реЗ willGetModifier рд╕реЗ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реВрдВ, рддреЛ рдореБрдЭреЗ рднреА рдпрд╣реА рд╕рдорд╕реНрдпрд╛ рд╣реИред рдмрд╣реБрдд - рдмрд╣реБрдд рдзрдиреНрдпрд╡рд╛рджред

рдпрджрд┐ рдХрд┐рд╕реА рдХреЛ рдпрд╣ рдорджрджрдЧрд╛рд░ рд▓рдЧрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ Google рдЗрд╕ рддреНрд░реБрдЯрд┐-рд╕рдВрджреЗрд╢ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рдЗрд╕ рдкреГрд╖реНрда рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИред
рдЗрд╕рдиреЗ рдХрдиреЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд╛рджрд╛-рдЖрдзрд╛рд░рд┐рдд рдЖрд╡рд░рдг рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдореЗрд░реА рдПрдХрд▓-рдХрдиреЗрдХреНрд╢рди-рдЖрдзрд╛рд░рд┐рдд рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд┐рдпрд╛ред рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдПрдХ рдЕрдЪреНрдЫрд╛ рд╕рдорд╛рдзрд╛рди рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдПрдХ рдЕрдиреБрднрд╡реА рдЬреЗрдПрд╕-рдбреЗрд╡рд▓рдкрд░ рдирд╣реАрдВ рд╣реВрдВ:

class PromisedConnection {
    constructor(config) {
        // this.connection always points to a promise resolving after the last assigned request
        // initial setting is either resolved once a new connection is established or rejected if an error occurs
        this.connection = new Promise((resolve, reject) => {
            const dbConnection = new Connection(config);
            dbConnection.on("connect", function (err) {
                if (err) {
                    reject(err);
                }
                else {
                    resolve(dbConnection);
                }
            });
        });
    }

    execute(request) {
        const nextConnection = new Promise((resolve, reject) => {
            // after scheduling new request this.connection should be reassigned to be the last in promise queue
            this.connection
                .catch( (reason) => {
                    reject(reason);
                } )
                .then( (dbConnection) => { // a new request can be executed only within the connection is free again (resolved after the last request)
                    request.on("requestCompleted", () => { // add an additional event listener in order to release connection after the request is done
                        resolve(dbConnection);
                    });
                    dbConnection.execSql(request);
                });
        } );
        this.connection = nextConnection;
    }
}

рдФрд░ рдХреНрд╡реЗрд░реА рдХреЛ рд╕реНрд╡рдпрдВ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

const dbConnection = new PromisedConnection(config);

function getObjList(query, parameters = []) {
    return new Promise((resolve, reject) => {
        const objList = [];
        let request = new Request(
            query,
            function (err, rowCount, rows) {
                if (err) {
                    reject(err);
                } else if (rowCount < 1) {
                    reject(new Error("0 rows returned from DB"));
                }
            }
        );
        for (const {name, type, value} of parameters) {
            request.addParameter(name, type, value);
        };

        request.on("row", (columns) => {
            objList.push(Obj.fromColumns(columns)); // here I just make a specific object from each row
        });

        request.on("requestCompleted", () => {
            resolve(objList);
        });

        dbConnection.execute(request);
    });
}

рддреЛ getObjList рдЕрдм рдХрдиреЗрдХреНрд╢рди рд╕реНрдерд┐рддрд┐ рдХреА рдЬрд╛рдВрдЪ рдХрд┐рдП рдмрд┐рдирд╛ рдХрд┐рд╕реА рднреА рд╕рдордп рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдпрд╣рд╛рдВ рдЪрд┐рдВрддрд╛ рдЕрдЪреНрдЫреА рд╣реИред рдореЗрд░реЗ рдХреЛрдб рдореЗрдВ рдореИрдВ рдПрдХ рдХрдиреЗрдХреНрд╢рди рдЕрдиреБрд░реЛрдз, рдПрдХ рдПрд╕рдХреНрдпреВрдПрд▓ рдЕрдиреБрд░реЛрдз, рдФрд░ рдлрд┐рд░ рдПрдХ рд╕рдореНрдорд┐рд▓рд┐рдд рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реВрдВред рдЬрдм рддрдХ рдореИрдВ рдПрд╕рдХреНрдпреВрдПрд▓ рдЕрдиреБрд░реЛрдз рдХреЗ рдмрд╛рдж requestCompleted рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рднреА рдПрд╕рдХреНрдпреВрдПрд▓ рдФрд░ рд╕рдореНрдорд┐рд▓рд┐рдд рдЕрдиреБрд░реЛрдз рдХреЗ рдмреАрдЪ рдПрдХ рдФрд░ рдХрдиреЗрдХреНрд╢рди рдЕрдиреБрд░реЛрдз рдирд╣реАрдВ рдХрд░рддрд╛, рддрдм рддрдХ рдпрд╣ рд╕рдореНрдорд┐рд▓рд┐рдд рдЕрдиреБрд░реЛрдз рдкрд░ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рдХрд░рддрд╛ рд╣реИред

рдЗрд╕ рддреНрд░реБрдЯрд┐ рдХрд╛ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдХрд╛рд░рдг рдпрд╣ рд╣реИ рдХрд┐ _рдПрдХ рд╕рдордп рдореЗрдВ рдХрдиреЗрдХреНрд╢рди рдкрд░ рдХреЗрд╡рд▓ рдПрдХ рдХреНрд╡реЗрд░реА рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред рдЖрдкрдХреЛ рдЕрдиреБрд░реЛрдз рдХреЙрд▓рдмреИрдХ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрдиреЗ рддрдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдпрд╛ рддреЛ рдПрдХ рддреНрд░реБрдЯрд┐ рдХреЗ рд╕рд╛рде рдпрд╛ рдХреЛрдИ рдЕрдиреНрдп рдЕрдиреБрд░реЛрдз рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд╕рд╛рдеред рдХреГрдкрдпрд╛ рдпрд╣рд╛рдВ рдЕрдХреНрд╕рд░ рдкреВрдЫреЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░рд╢реНрди рдкреГрд╖реНрда рдкрд░ рдЬрд╛рдПрдВ

рдЪреВрдВрдХрд┐ рдЗрд╕ рдордВрдЪ рдкрд░ рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╡рд┐рднрд┐рдиреНрди рдореБрджреНрджреЗ рдкреНрд░рддреАрдд рд╣реЛрддреЗ рд╣реИрдВред рддреНрд░реБрдЯрд┐ Requests can only be made in the LoggedIn state, not the SentClientRequest state рд╡рд┐рднрд┐рдиреНрди рдХрд╛рд░рдгреЛрдВ рд╕реЗ рд╣реЛ рд╕рдХрддреА рд╣реИред рдпрджрд┐ рдЖрдк рдЗрд╕ рддреНрд░реБрдЯрд┐ рдХрд╛ рдЕрдиреБрднрд╡ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЖрдкрдХреЛ рдЕрдХреНрд╕рд░ рдкреВрдЫреЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░рд╢реНрди рдкреГрд╖реНрда рдорджрджрдЧрд╛рд░ рдирд╣реАрдВ рд▓рдЧреЗ, рддреЛ рдХреГрдкрдпрд╛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд╕рд╛рде рдЕрдкрдиреА рд╕рдорд╕реНрдпрд╛ рд╕реНрд╡рдпрдВ рдЙрдард╛рдПрдВ рддрд╛рдХрд┐ рд╣рдо рдЖрдкрдХреА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдЕрдзрд┐рдХ рд╕рдЯреАрдХрддрд╛ рдХреЗ рд╕рд╛рде рд╕рдорд╛рдзрд╛рди рдХрд░ рд╕рдХреЗрдВ:

  • рдердХрд╛рдК рд╕рдВрд╕реНрдХрд░рдг
  • рдХрдиреЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдЖрдкрдХрд╛ рд╡рд┐рдиреНрдпрд╛рд╕
  • рдПрдХ рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╕реНрдХреНрд░рд┐рдкреНрдЯ

рдзрдиреНрдпрд╡рд╛рдж! рдореИрдВ

рдЗрд╕реЗ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдерд╛, рд╕рдорд╕реНрдпрд╛ рдореЗрд░реА рддрд░рдл рдереА, рдпрд╣ рдирд╣реАрдВ рдкрддрд╛ рдерд╛ рдХрд┐ рдЖрдкрдХреЛ рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдХрдиреЗрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ

@mgarf рдЖрдкрдХрд╛ рд╕рдорд╛рдзрд╛рди рдХреНрдпрд╛ рдерд╛? рдореБрдЭреЗ рдпрд╣ рднреА рдирд╣реАрдВ рдкрддрд╛ рдерд╛ рдХрд┐ рдореБрдЭреЗ рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдХрдиреЗрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдореИрдВ рдЗрд╕ рдЪрд░реНрдЪрд╛ рдореЗрдВ рдЕрдиреНрдп рд▓реЛрдЧреЛрдВ рдХреА рддрд░рд╣ рд╕рдорд╡рд░реНрддреА рдореБрджреНрджреЛрдВ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред

@mikebutak рдЖрдкрдХреЛ рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдХрдиреЗрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдПрдХ рдХрдиреЗрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдЕрдиреБрд░реЛрдз _at a time_ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИред рдПрдХ рдХрдиреЗрдХреНрд╢рди рдкрд░ рдХрдИ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдкрд┐рдЫрд▓реЗ рдПрдХ рдХреЗ рдХреЙрд▓рдмреИрдХ рдореЗрдВ рдПрдХ рдирдпрд╛ рдЕрдиреБрд░реЛрдз рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рд╕рдорд╛рдкреНрдд рд╣реЛрдиреЗ рдХреЗ рдмрд╛рджред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,

function executeStatement() {
  request = new Request("select 42, 'hello world'", function(err, rowCount) {
    if (err) {
      console.log(err);
    } else {
      console.log(rowCount + ' rows');
    }

    connection.execSql(new Request("select 42, 'hello world'", function(err, rowCount) {
      if (err) {
        console.log(err);
      } else {
        console.log(rowCount + ' rows');
      }
      connection.close();
    }))
  });
  connection.execSql(request);

рдореИрдВ рдЗрд╕ рдореБрджреНрджреЗ рдХреЗ рд▓рд┐рдП рдХреЙрд▓рдмреИрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдкреВрд░реНрдг рд╕рдорд╛рдзрд╛рди рдкреЛрд╕реНрдЯ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдореБрдЭреЗ рднреА рдпрд╣реА рд╕рдорд╕реНрдпрд╛ рдереА рдФрд░ рдЬрдм рдореИрдВ Google рдХреЛ рджреЗрдЦ рд░рд╣рд╛ рдерд╛ рддреЛ рдореИрдВ рдпрд╣рд╛рдБ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдпрд╛ред рдореИрдВрдиреЗ рдЗрд╕ рдХреЛрдб рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╣рд░ рд╕реЗрдХреЗрдВрдб рдореЗрдВ 1 http рдХреЙрд▓ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╕рдорд╕реНрдпрд╛ рдХреЗ рдЖрдзрд╛ рд╕реЗрдХреЗрдВрдб рднреА рд╣реЛрддрд╛ рд╣реИред

const {Connection, Request} = require("tedious");

const executeSQL = (sql, callback) => {
  let connection = new Connection({
    "authentication": {
      "options": {
        "userName": "USERNAME",
        "password": "PASSWORD"
      },
      "type": "default"
    },
    "server": "SERVER",
    "options": {
      "validateBulkLoadParameters": false,
      "rowCollectionOnRequestCompletion": true,
      "database": "DATABASE",
      "encrypt": true
    }
  });

  connection.connect((err) => {
    if (err)
      return callback(err, null);

    const request = new Request(sql, (err, rowCount, rows) => {
      connection.close();

      if (err)
        return callback(err, null);

      callback(null, {rowCount, rows});
    });

    connection.execSql(request);
  });
};

executeSQL("SELECT * FROM users", (err, data) => {
  if (err)
    console.error(err);

  console.log(data.rowCount);
});

//or

executeSQL("SELECT * FROM users", (err, {rowCount, rows}) => {
  if (err)
    console.error(err);

  console.log(rowCount);
});

рдореИрдВ рдЗрд╕ рдореБрджреНрджреЗ рдХреЗ рд▓рд┐рдП рдХреЙрд▓рдмреИрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдкреВрд░реНрдг рд╕рдорд╛рдзрд╛рди рдкреЛрд╕реНрдЯ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдореБрдЭреЗ рднреА рдпрд╣реА рд╕рдорд╕реНрдпрд╛ рдереА рдФрд░ рдЬрдм рдореИрдВ Google рдХреЛ рджреЗрдЦ рд░рд╣рд╛ рдерд╛ рддреЛ рдореИрдВ рдпрд╣рд╛рдБ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдпрд╛ред рдореИрдВрдиреЗ рдЗрд╕ рдХреЛрдб рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╣рд░ рд╕реЗрдХреЗрдВрдб рдореЗрдВ 1 http рдХреЙрд▓ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╕рдорд╕реНрдпрд╛ рдХреЗ рдЖрдзрд╛ рд╕реЗрдХреЗрдВрдб рднреА рд╣реЛрддрд╛ рд╣реИред

const {Connection, Request} = require("tedious");

const executeSQL = (sql, callback) => {
  let connection = new Connection({
    "authentication": {
      "options": {
        "userName": "USERNAME",
        "password": "PASSWORD"
      },
      "type": "default"
    },
    "server": "SERVER",
    "options": {
      "validateBulkLoadParameters": false,
      "rowCollectionOnRequestCompletion": true,
      "database": "DATABASE",
      "encrypt": true
    }
  });

  connection.connect((err) => {
    if (err)
      return callback(err, null);

    const request = new Request(sql, (err, rowCount, rows) => {
      connection.close();

      if (err)
        return callback(err, null);

      callback(null, {rowCount, rows});
    });

    connection.execSql(request);
  });
};

executeSQL("SELECT * FROM users", (err, data) => {
  if (err)
    console.error(err);

  console.log(data.rowCount);
});

//or

executeSQL("SELECT * FROM users", (err, {rowCount, rows}) => {
  if (err)
    console.error(err);

  console.log(rowCount);
});

рдпрд╣ рд╕рдорд╛рдзрд╛рди рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рдпрд╣ рдПрдХ рд╡реИрдз рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ? рдпрд╣ рдХрд┐рддрдирд╛ рд╡реНрдпрд╡рд╣рд╛рд░реНрдп рд╣реИ, рдпрд╣ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ рд╕реИрдХрдбрд╝реЛрдВ рд╣рдЬрд╛рд░реЛрдВ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпрд╛рдВ/рдЪрдпрди рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рд▓рд┐рдП рдХрдиреЗрдХреНрд╢рди рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ? рд╕рдорд╛рдзрд╛рди рдмреАрдЯреАрдбрдмреНрд▓реНрдпреВ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдореИрдВ рд╕рд┐рд░реНрдл рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рдПрдХ рд╡реНрдпрд╡рд╣рд╛рд░реНрдп рд╕рдорд╛рдзрд╛рди рд╣реИ рдпрд╛ рдирд╣реАрдВред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдпрджрд┐ рд╣рдо Azure рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ?

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

David-Engel picture David-Engel  ┬╖  5рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

anthonylau picture anthonylau  ┬╖  8рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

spacem picture spacem  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

jstephens7 picture jstephens7  ┬╖  5рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

SaloniSonpal picture SaloniSonpal  ┬╖  5рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ