Quantcast
Channel: campusMVP.es
Viewing all articles
Browse latest Browse all 776

Cómo consultar una base de datos SQL Server desde NodeJS

$
0
0

Últimamente me ha tocado trabajar con node.js consumiendo datos de la base de datos documental MongoDB y también desde SQL Server. Buscando información he podido probar varios conectores y paquetes que nos facilitan el trabajo a la hora de la conexión y de la creación de consultas.

Para conectarme con SQL Server he utilizado Tedious. Se trata de un paquete que puedes descargar vía npm y que implementa el protocolo TDM. Tedious funciona tanto en servidores Linux como en Windows. El nombre de este paquete hace referencia a que la pronunciación en inglés de TDS es parecida a la de tedious (tedioso en inglés) 😁

Para la creación de consultas utilizo otro paquete llamado json-sql, que me permite crear consultas SQL a partir de objetos JSON (como por ejemplo en MongoDB). Ojo: este paquete se trata de un traductor, en ningún caso es un conector.

Su sintaxis es muy simple. Por ejemplo para realizar una consulta de selección hacemos lo siguiente:

1.- Importamos el paquete:

let jsonSql = require('json-sql');

Nos fijamos que ya estamos creando una instancia de json-sql.

2.- Creamos una función para obtener el objeto que creará la consulta:

createSelectQuery(filter, sort) {
let sql = jsonSql.build({
dialect: 'mssql',
type: 'select',
table: 'Direcciones',
fields: ['Id', 'Cif', 'NombreRazonSocial',
'Direccion', 'CodigoPostal', 'Poblacion',
'Provincia', 'ComunidadAutonoma',
'Pais', 'FechaModificacion'],
condition: filter,
sort: sort
});
return sql;
}

Vamos a desglosar un poco esta función...

Primeramente destacamos el objeto jsonSql, que es el principal de la biblioteca. Posee un método buid al cual le podemos especificar, entre otros,  los siguientes parámetros:

  • El dialecto que vamos a utilizar ('base', 'mssql', 'mysql', 'postgresql' o 'sqlite').
  • El tipo de consulta (en este caso SELECT)
  • La tabla o tablas con las que vamos a trabajar (se pueden hacer joins, agrupaciones...)
  • Los campos que queremos proyectar
  • Los filtros (WHERE)
  • La ordenación
  • ...

En la función anterior, las variables filter y sort asignados a las propiedades condition y sort respectivamente, son documentos JSON. Por ejemplo:

let sql = jsonSql.build({
    table: 'table',
    condition: {Nombre: 'Miguel'}
    sort: {a: 1, b: -1}
});

En este ejemplo el objeto sql tiene una propiedad query que contiene la consulta SQL resultante, así:

sql.query = 'select * from "table" WHERE Nombre = "Miguel" order by "a" asc, "b" desc';

3.- Una vez tenemos la consulta, vamos a atacar a la base de datos. Vamos a usar promesas para realizar llamadas asíncronas. Existe un paquete llamado bluebird que nos facilita mucho su creación. Veamos cómo usarlo:

3.1.- Importamos el paquete:

const promise = require('bluebird');

3.2.- He creado una función executeQuery para gestionar la conexión con la base de datos y la ejecución de consultas en la que importo las clases SqlConnection y Request:

const SqlConnection = require("tedious").Connection;
const Request = require("tedious").Request;

executeQuery(query) {
        let resultEntity = {
            result: {},
            error: null
        };

        return new promise((resolve, reject) => {
            var connection = new SqlConnection(this.config);

            connection.on('connect', function (err) {
                let request = new Request(query, function (err, rowCount, rows) {
                    if (err) {
                        resultEntity.error = err;
                        reject(resultEntity);
                    } else {
                        resultEntity.result = rows;
                        resolve(resultEntity);
                    }

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

En esta función primero creo una entidad resultEntity que será la que se devuelva con el resultado obtenido de la consulta e información en caso de que se produzca algún error. Después está la promise, en la que se establece la conexión creando un objeto de tipo SqlConnection al que se le pasa la configuración en el constructor. Esta configuración tiene el siguiente aspecto:

"config": {
  "server": "servidor",
  "userName": "Usuario",
  "password": "clave",
  "options": {
     "instanceName": "Nombre de la instancia",
     "database": "nombre base de datos",
     "rowCollectionOnRequestCompletion": true,
     "rowCollectionOnDone": true
  }
}

Puedes encontrar más información al respecto de esta configuración en la documentación de Tedious.

A continuación nos subscribimos al evento connect de la conexión y creamos un objeto de tipo request, al  cual le pasamos como primer parámetro la consulta a realizar. Este objeto request va a ser el encargado de gestionar la consulta y devolver los resultados (rows) o si se produce algún error (err).

Se procede a cerrar la conexión:

connection.close();

Y después de la subscripción al evento connect procedemos a ejecutar la consulta mediante el método execSql de la conexión, el cual recibe como parámetro el objeto request que acabamos de crear.

En definitiva lo que realiza esta función es:

  • Crea el objeto a devolver por la función
  • Crea el objeto de conexión
  • Se subscribe al evento connect de la conexión
  • Crea el objeto request para hacer la petición a la base de datos y recibir los resultados
  • Ejecuta la consulta

El objeto recibido devuelve los valores de la consulta así como los metadatos de cada campo solicitado.

¡Espero que os sea de utilidad!


Viewing all articles
Browse latest Browse all 776

Trending Articles