Skip to content

Instantly share code, notes, and snippets.

@FRodrigues21
Last active April 23, 2020 20:37
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save FRodrigues21/7df3b3c5e4a0cd49bde53d684cd10c88 to your computer and use it in GitHub Desktop.
Save FRodrigues21/7df3b3c5e4a0cd49bde53d684cd10c88 to your computer and use it in GitHub Desktop.
πŸ”Ž Example of Tedious SQL Server DB controller in Node.js (non-concurrent)
var Connection = require("tedious").Connection;
var Request = require("tedious").Request;
var ConnectionPool = require("tedious-connection-pool");
// Avoiding concurrent SQL SERVER calls
var poolConfig = {
min: 1,
max: 1,
log: true
};
// Edit this config
var connectionConfig = {
userName: "username",
password: "password",
server: "ipaddress",
options: {
rowCollectionOnDone: true, // Only get row set instead of row by row
useColumnNames: true // For easier JSON formatting
}
};
var _rows = [];
var pool = new ConnectionPool(poolConfig, connectionConfig);
pool.on("error", function(err) {
console.error(err);
});
var _rows = [];
const query = (params, sql, callback) => {
pool.acquire((err, connection) => {
request = new Request(sql, (err, rowCount) => {
if (err) {
console.log(err);
return;
}
connection.release();
});
if (params.length > 0) {
params.forEach(param => {
request.addParameter(param.name, param.type, param.value);
});
}
_rows = [];
request.on("row", columns => {
var _item = {};
// Converting the response row to a JSON formatted object: [property]: value
for (var name in columns) {
_item[name] = columns[name].value;
}
_rows.push(_item);
});
// We return the set of rows after the query is complete, instead of returing row by row
request.on("doneInProc", (rowCount, more, rows) => {
callback(_rows);
});
connection.execSql(request);
});
};
const proc = (params, sql, callback) => {
pool.acquire((err, connection) => {
request = new Request(sql, (err, rowCount) => {
if (err) {
console.log(err);
return;
}
connection.release();
});
if (params.length > 0) {
params.forEach(param => {
request.addParameter(param.name, param.type, param.value);
});
}
_rows = [];
request.on("row", columns => {
var _item = {};
// Converting the response row to a JSON formatted object: [property]: value
for (var name in columns) {
_item[name] = columns[name].value;
}
_rows.push(_item);
});
// We return the set of rows after the procedure is complete, instead of returing row by row
request.on("doneProc", (rowCount, more, rows) => {
callback(_rows);
});
connection.callProcedure(request);
});
};
const buildParams = (params, name, type, value) => {
params.push({
name: name,
type: type,
value: value
});
};
module.exports = {
buildParams: buildParams,
query: query,
proc: proc
};
var db = require("./dbController.js");
var TYPES = require("tedious").TYPES;
// QUERY
// Imagine we have a table called pokemon with 2 attributes: name and number
// We want to find a pokemon by number, using a select query
const getPokemon = (number) => {
var params = [];
var sql = "select * from pokemon where number = @number";
// For each param do: db.buildParams(params, "name", TYPES.type, variable)
db.buildParams(params, "number", TYPES.Int, number);
db.query(params, sql, result => {
console.log(result);
});
}
// PROCEDURE
// The same as above but using instead a procedure called findPokemon(number)
const getPokemonProc = (number) => {
var params = [];
var sql = "findPokemon"; // instead of query selector use only procedure name
// For each param do: db.buildParams(params, "name", TYPES.type, variable)
db.buildParams(params, "number", TYPES.Int, number); // Params will be added automatically to the procedure exec
db.proc(params, sql, result => { // Just need to change from query to proc
console.log(result);
});
}
getPokemon(132);
getPokemonProc(34);
module.exports = {
getPokemon: getPokemon,
getPokemonProc: getPokemonProc
}
@blitzkriegcoding
Copy link

How I do for return the values to controller, from the model?

@genesisemmloh
Copy link

genesisemmloh commented Sep 16, 2019

Hi man, could you take some time to help me?
IΒ΄ve implemented something similar but i always get this error, this happend at the execSql method:
TypeError: cb is not a function
at Object.writeParameterData

maybe if you have interest to help
i would show you my code, Thanks in advanced


private getLocations(argUrlParams?: object | undefined): Promise<any[]> {

    console.log(" get Locations from DB");
    const TYPES = tedious.TYPES;
    let queryText = queries.locations;
    const Request = tedious.Request;
    // Read all rows from table

    queryText = queries.locations.replace(`%ConditionalInnerJoin%`, "");
    queryText = queryText.replace(`%ConditionalWhere%`, "");

    const parameters: any[] = [];

    parameters.push(
      {
        name: "accountId",
        type: TYPES.Int,
        value: Object.values(argUrlParams)[0]
      });
    parameters.push(
      {
        name: "companyNumber",
        type: TYPES.Int,
        value: Object.values(argUrlParams)[1]
      });

    return new Promise<any[]>((resolve) => {
      this.readTable(queryText, parameters, (result) => {
        resolve(result);
      })
    })
  }


  private readTable(argQueryText: string, argParameters: any[], argCallBack: (n: any[]) => any): any[] {
    // Attempt to connect and execute queries if connection goes through
    const TYPES = tedious.TYPES;
    const jsonArray: any[] = [];

    console.log("-1");
    // tslint:disable-next-line: no-shadowed-variable
    this.pool.acquire((err, connection) => {
      console.log("0");
      if (err) {
        console.log(err);
        argCallBack(jsonArray);
      }

      console.log("===SQLConnectionManager πŸ”Œ Establishing connection===");

      try {

        const request = new tedious.Request(argQueryText, (error, rowCount) => {
          if (error) {
            console.log('a jijo');

            console.log(error);
            return;
          }
          console.log(rowCount + " row(s) returned");
          connection.release();
        });

        if (argParameters.length > 0) {
          argParameters.forEach(param => {
            request.addParameter(param.name, param.type, param.value);
          });
        }

        console.log("1");
        request.on("row", (columns: any) => {
          const rowObject: any = {};
          //  console.log('2');
          columns.forEach((column: any) => {
            rowObject[column.metadata.colName] = column.value;
          });
          jsonArray.push(rowObject);
        });

        console.log("3");

        request.on("doneInProc", (rowCount, more, rows) => {
          console.log("5");
          return argCallBack(jsonArray);;
        });

        connection.execSql(request);
        console.log("4");
      } catch (error) {
        console.log('error en el catch');
        console.log(error);
        connection.release();
        argCallBack(jsonArray);
      }

    })

    return jsonArray;
  }

@HuguesGauthier
Copy link

replace type.writeParameterData(buffer, param, options);
with: type.writeParameterData(buffer, param, options, ()=>{});
"at new RpcRequestPayload (D:\Projects\Statistics\node_modules\tedious-connection-pool\node_modules\tedious\lib\rpcrequest-payload.js:95:12)"

@genesisemmloh
Copy link

yes, thanks i solved this exactly like that, but you know this problem will occur every time a new npm install its executed

@makitocode
Copy link

Why you suggest avoid concurrent SQL calls ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment