Использование SQL Server в Node.js
В сегодняшней статье мы подробно рассмотрим как настроить и использовать SQL Server при разработке веб-сайта на Node.js.
Установка SQL Service Module
NPM обладает множеством модулей для работы с SQL Server. В командной строке мы можем использовать команду «npm find» для поиска необходимых расширений для Node,js. На следующем изображении я ввел команду «npm find sqlserver», и в результатах поиска мы видим все модули для интеграции с SQL Server.
В рамках статьи мы рассмотрим модуль node-sqlserver. Данный модуль был разработан корпорацией Microsoft. Он использует библиотеки, построенные на языке C++, а в качестве «моста» - API JavaScript и внутренний сервер SQL Native Client. Когда вы загрузите и установите этот модуль, он будет скомпилирован С++ сценарием, написанным на Python.
Следовательно, существуют некоторые системные требования для компонентов:
- Node.js: рекомендуемая версия 0.6.10 или выше.
- Python версии 2.7.x
- Visual C + + 2010. Подойдет программное обеспечение редакции Visual Studio Express 2010 и выше.
- SQL Server Native Client 11.0. Можно найти в пакете SQL Server 2012 Feature Pack.
Если у вас имеются все перечисленные компоненты, вы можете приступать к установке модуля node-sqlserver, которая задается командой «npm install node-sqlserver».
В процессе установки может возникнуть ошибка отсутствия файла SQL-клиента. Для решения проблемы вам необходимо скопировать этот файл вручную. Допустим, вы установили модуль node-sqlserver в папку c:\Program Files\nodejs\apps\. Вам необходимо найти файл «sqlserver.node» в c:\Program Files\nodejs\apps\node_modules\node-sqlserver\build\Release и скопировать его с таким же названием и расширением в папку c:\Program Files\nodejs\apps\node_modules\node-sqlserver\lib
SQL-запросы в Node.js
Мы будем использовать стандартную базу данных, которая содержит только одну таблицу с 3 колонками.
Полная схема для создания сценария .sql находится в прикрепленном файле.
Для подключения модуля node-sqlserver к SQL Server необходимо в начале импортировать его в проект. Первый параметр - строка подключения, в то время как второй параметр - обратный вызов, который сработает, если соединение было открыто или, наоборот, закрыто.
var sql = require("node-sqlserver");
var connectionString = "Driver={SQL Server Native Client 11.0};Server={.};Database={Caspar};Trusted_Connection={Yes};";
sql.open(connectionString, function(err, conn) {
if(err) {
// код обработчика ошибок
}
else {
}
});
Как только мы открыли соединение, можно выполнить любые команды T-SQL через функцию "queryRaw". У этой функции есть два параметра. Первый – собственно T-SQL команда, второй параметр – функция обратного вызова, которая запускается один раз в зависимости от того был запрос выполнен или нет:
sql.open(connectionString, function(err, conn) {
if(err) {
// код обработчика ошибок
}
else {
var command = "{YOUR_COMMAND_HERE}";
conn.queryRaw(command, function(err, results) {
if(err) {
// код обработчика ошибок
}
else {
// результат в формате JSON
}
});
}
});
Параметр "results" отображает все записи в формате JSON. Он состоит из двух частей. В первой части под названием "meta" содержится информация о метаданных каждого столбца результата. Вторая часть под названием "rows" представляет собой массив из всех записей.
Ниже приведен пример запроса к таблице, которую мы только что создали. В «meta» части есть три колонки, в которых указаны поля Key, Culture, Value их и спецификации. В части «rows» мы видим массив всех записей базы данных.
Следовательно, если мы хотим получить данные из базы данных, нужно использовать массив. В настоящее время модуль не поддерживает получение результатов значения из имени столбца.
conn.queryRaw(command, function(err, results) {
if(err) {
// код обработчика ошибок
}
else {
for(var i = 0; i < result.rows.length; i++) {
console.log(i + ": " + "Key = " + result.rows[i][0]);
console.log(i + ": " + "Culture = " + result.rows[i][1]);
console.log(i + ": " + "Value = " + result.rows[i][2]);
}
}
});
Давайте создадим простой веб-сервер, чтобы продемонстрировать как использовать модуль node-sqlserver. Для этого мы будем использовать стандартное приложение hellosql.js с установленными модулями «express» и «node-sqlserver». При переходе на главную страницу будет происходить соединение с базой данных с выдачей результатов в формате JSON:
var express = require("express");
var sql = require("node-sqlserver");
var app = express();
var connectionString = "Driver={SQL Server Native Client 11.0};Server={.};Database={Caspar};Trusted_Connection={Yes};";
app.configure(function () {
app.use(express.bodyParser());
});
app.get("/", function(req, res) {
sql.open(connectionString, function(err, conn) {
if(err) {
console.log(err);
res.send(500, "Cannot open connection.");
}
else {
conn.queryRaw("SELECT * FROM [Resource]", function(err, results) {
if(err) {
console.log(err);
res.send(500, "Cannot retrieve records.");
}
else {
res.json(results);
}
});
}
});
});
app.listen(10000);
Так как в настоящее время node-sqlserver не поддерживает SQL параметры, нам придется использовать текстовые комбинации для указания критериев запроса. В следующем листинге добавлен запрос с поиском по ключу и типу, выполняемый приложением node.js автоматически:
app.get("/text/:key/:culture", function(req, res) {
sql.open(connectionString, function(err, conn) {
if(err) {
console.log(err);
res.send(500, "Cannot open connection.");
}
else {
var key = req.params.key;
var culture = req.params.culture;
var command = "SELECT * FROM [Resource] WHERE [Key] = '" + key + "' AND [Culture] = '" + culture + "'";
conn.queryRaw(command, function(err, results) {
if(err) {
console.log(err);
res.send(500, "Cannot retrieve records.");
}
else {
res.json(results);
}
});
}
});
});
Результат будет таким:
Добавление, удаление, вставка данных в node.js
Как мы уже говорили выше, функция queryRaw может быть использована для вставки, обновления и удаления строк в базе данных. Фактически мы можем применять любые команды T-SQL в этой функции.
В следующем примере для пользователя добавлен маршрут, чтобы вставить новую запись в базу данных. Пользователь должен отправить запрос методом HTTP POST и указать значение в теле запроса. Приложение получит значение, объединит команду SQL и затем вызовет модуль node-sqlserver, чтобы вставить данные.
app.post("/new", function(req, res) {
var key = req.body.key;
var culture = req.body.culture;
var val = req.body.val;
sql.open(connectionString, function(err, conn) {
if(err) {
console.log(err);
res.send(500, "Cannot open connection.");
}
else {
var command = "INSERT INTO [Resource] VALUES ('" + key + "', '" + culture + "', '" + val + "')";
conn.queryRaw(command, function(err, results) {
if(err) {
console.log(err);
res.send(500, "Cannot retrieve records.");
}
else {
res.send(200, "Inserted Successful");
}
});
}
});
});
Так как мы должны использовать метод POST, запустим процесс с помощью консольного приложения в C#.
class Program
{
static void Main(string[] args)
{
var key = args[0];
var culture = args[1];
var val = args[2];
var req = HttpWebRequest.Create("http://EPEKW-Q1100423.is.ad.igt.com:10000/new");
req.ContentType = "application/x-www-form-urlencoded";
req.Method = WebRequestMethods.Http.Post;
var param = string.Format("key={0}&culture={1}&val={2}", key, culture, val);
var bytes = System.Text.Encoding.UTF8.GetBytes(param);
req.ContentLength = bytes.Length;
using(var stream = req.GetRequestStream())
{
stream.Write(bytes, 0, bytes.Length);
}
var res = req.GetResponse();
using (var sr = new StreamReader(res.GetResponseStream()))
{
Console.WriteLine(sr.ReadToEnd());
}
Console.ReadKey();
}
}
Давайте запустим это консольное приложение и введем значение (пример: ConsoleApplication.exe MY_SAMPLE_RESOURCE en-US "My sample resource in en-US"), которое будут вставлено в базу данных.
Вернемся в базу данных и посмотрим наш результат.
В сегодняшней статье мы рассмотрели вопросы, связанные с интеграцией SQL Server с приложением Node.js, особенностями запросов и функциях вывода с использованием модуля node-sqlserver.
В следующий раз мы расскажем, как запустить приложение Node.js в Windows Azure и как подключить готовый проект к Windows Azure SQL Database.