В этом уроке вы узнаете, как использовать поток для более эффективной обработки больших наборов результатов.
Это руководство начинается с того места, где закончилось руководство Вызов хранимой процедуры с параметром OUTPUT в Node.js.
Как использовать поток Node.js для обработки больших наборов результатов
Поток позволяет эффективно обрабатывать большой набор результатов, обрабатывая его построчно, а не загружая его в память сразу.
Поток полезен при обработке больших наборов результатов из SQL Server без использования большого объема памяти сервера.
Ниже описаны шаги по использованию потока:
Сначала подключитесь к SQL Server :
const pool = await sql.connect(config);
Во-вторых, создайте объект Request, который представляет запрос, выполняемый к SQL Server, и включает потоковую передачу:
const request = new sql.Request(pool); request.stream = true;
В-третьих, обрабатывайте данные по мере их поступления. Для этого используется метод on() объекта Request. Метод request.on() обрабатывает различные события, которые происходят во время выполнения запроса, когда поток включен:
- набор записей: срабатывает, когда доступны метаданные столбцов.
- строка: срабатывает для каждой строки в наборе результатов.
- ошибка: срабатывает при возникновении ошибки.
- done: срабатывает после завершения выполнения запроса.
Например, ниже показано, как обрабатывать каждую строку данных по мере их поступления с помощью request.on() с событием строки:
request.on('row', row => {
console.log('Row:', row);
});
Пример потоковой передачи данных в файл CSV
Мы покажем вам, как запросить данные из таблицы Authors и передать их напрямую в файл, чтобы избежать загрузки всего в память:
Шаг 1. Создайте новый файл с именем stream.js в каталоге проекта.
Шаг 2. Определите функцию exportAuthorsToCSV, которая экспортирует все строки из таблицы Authors в CSV-файл:
import fs from 'fs';
import sql from 'mssql';
import { config } from './config.js';
const exportAuthorsToCSV = async(csvFilename) => {
try {
// Create a write stream for the CSV file
const writeStream = fs.createWriteStream(csvFilename);
// Connect to the database
const pool = await sql.connect(config);
// Create a new request with streaming enabled
const request = new sql.Request(pool);
request.stream = true;
// Execute the query
request.query('SELECT * FROM Authors ORDER BY FirstName');
// Event handlers for the streaming
request.on('recordset',(columns) => {
let header = '';
for(const column in columns) {
header += `${column},`;
}
// remove the last comma(,)
header = header.slice(0, -1);
// write the header
writeStream.write(header + '\n');
});
// Process each row when it is arrived
request.on('row',({ AuthorID, FirstName, LastName, BirthDate }) => {
const csvRow = `${AuthorID},${FirstName},${LastName},${BirthDate.toLocaleDateString()}`;
writeStream.write(csvRow + '\n');
});
// Error handlers for the request
request.on('error',(err) => {
console.error('Error:', err);
writeStream.end();
});
// Event handler for when the query is done
request.on('done',(result) => {
console.log('Query done. Rows affected:', result.rowsAffected);
writeStream.end();
});
} catch(err) {
console.error(err);
}
};
export { exportAuthorsToCSV };
Как это работает.
Сначала импортируйте объекты fs, sql и config из модулей fs, mssql и config.js соответственно.
import fs from 'fs';
import sql from 'mssql';
import { config } from './config.js';
Во-вторых, определите функцию exportAuthorsToCSV, которая принимает имя файла CSV:
const exportAuthorsToCSV = async(csvFilename) => {
//...
};
В-третьих, создайте поток записи для CSV-файла:
const writeStream = fs.createWriteStream(csvFilename);
В-четвертых, подключитесь к SQL Server, используя предоставленный объект конфигурации.
const pool = await sql.connect(config);
Обратите внимание, что объект конфигурации содержит необходимые параметры для подключения к SQL Server, включая имя пользователя, пароль, сервер и имя базы данных:
В-пятых, создайте новый запрос с включенной потоковой передачей:
const request = new sql.Request(pool); request.stream = true;
В-шестых, выполните запрос, который извлекает данные из таблицы Authors:
request.query('SELECT * FROM Authors ORDER BY FirstName');
В-седьмых, запишите заголовок CSV-файла один раз в обработчике событий набора записей:
request.on('recordset',(columns) => {
let header = '';
for(const column in columns) {
header += `${column},`;
}
// remove the last comma(,)
header = header.slice(0, -1);
// write the header
writeStream.write(header + '\n');
});
Как это работает.
- Инициализируйте заголовок пустой строкой.
- Выполните итерацию по свойствам объекта columns с помощью цикла for…in и объедините имена свойств(AuthorID, FirstName, LastName и BirthDate) в одну строку. Обратите внимание, что объект columns содержит все поля в таблице Authors, включая AuthorID, FirstName, LastName и BirthDate.
- Удалите последнюю запятую(,) из строки заголовка с помощью метода slice().
- Запишите заголовок в CSV-файл, вызвав метод write() объекта writeStream.
Восьмое, записывайте каждую строку в CSV-файл, когда она поступает в обработчик событий строки:
request.on('row',({ AuthorID, FirstName, LastName, BirthDate }) => {
const csvRow = `${AuthorID},${FirstName},${LastName},${BirthDate.toLocaleDateString()}`;
writeStream.write(csvRow + '\n');
});
Девятое, если произошла ошибка, выведите ее на консоль и завершите поток в обработчике событий ошибки:
request.on('error',(err) => {
console.error('Error:', err);
writeStream.end();
});
В-десятых, выведите сообщение на консоль и завершите поток в обработчике событий done:
request.on('done',(result) => {
console.log('Query done. Rows affected:', result.rowsAffected);
writeStream.end();
});
Одиннадцатое, выведите сообщение об ошибке на консоль в блоке catch:
console.error(err);
Наконец, экспортируйте функцию exportAuthorsToCSV.
Шаг 3. Измените index.js для использования функции exportAuthorsToCSV:
import { exportAuthorsToCSV } from './stream.js';
exportAuthorsToCSV('data/output.csv');
Как это работает.
Сначала импортируйте функцию exportAuthorsToCSV из модуля stream.js.
import { exportAuthorsToCSV } from './stream.js';
Во-вторых, вызовите функцию exportAuthorsToCSV() для экспорта данных об авторе в CSV-файл, расположенный по адресу data/output.csv:
exportAuthorsToCSV('data/output.csv');
Шаг 4. Откройте терминал и выполните следующую команду для запуска файла index.js:
npm start
Если программа отработает успешно, вы увидите новый выходной файл output.csv в каталоге данных:
AuthorID,FirstName,LastName,BirthDate 2,Agatha,Christie,9/15/1890 9,Charles,Dickens,2/7/1812 22,Emily,Bronte,7/30/1818 ...
Краткое содержание
- Используйте поток для эффективной обработки больших наборов результатов.
- Установите свойство stream объекта Request на true, чтобы включить потоковую передачу.
- Используйте метод request.on() для обработки событий, возникающих во время выполнения запроса после включения потоковой передачи.

