質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Q&A

解決済

1回答

1876閲覧

Node.js SQLServer 複数SQLの実行方法

miyawaki

総合スコア11

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

0グッド

0クリップ

投稿2019/08/14 02:24

windows環境にて
Node.js+Express+SQLServerでアプリ開発を行おうとしております。

下記のサイトを参考に、jsにてDB接続、SQLの実行を行い、結果をejsにて表示させています。
http://hiyo-ac.hatenablog.com/entry/2018/01/28/141831

SQLが1つ(表が1つ)の場合はうまく動作することが確認できましたが、
1つの画面に複数の表を設置(複数SQLを実行し、複数の結果を取得・表示)したい場合、どうコーディングしたら良いのかがわかりません。

ソースは下記のとおりです。(上記サイトそのままです)

router.get('/', function(req, res, next) { var connection = new Connection(config); var content = []; // DBからselectした結果を格納する変数 // DB接続した際のイベントハンドラ connection.on('connect', function(err){ console.log("connected"); executeStatement(); }); // DB接続を終了した際のイベントハンドラ // DB接続を切断した後に画面を描写する connection.on('end', function(){ console.log("disconnected"); res.render('sample', { title: 'sqlserver-sample', content: content }); }); var Request = require('tedious').Request; // SQLを発行する関数 function executeStatement(){ // 発行するSQLを記載する request = new Request("SELECT * FROM TestDB.dbo.TB_TestTable with (NOLOCK)", function(err){ if(err){ console.log(err);} }); var result = {}; // SQLの結果を行ごとにオブジェクトに格納する。 // SQLの行ごとに実行するイベントハンドラ request.on('row', function(columns){ columns.forEach(function(column){ if(column.value === null){ console.log('NULL'); }else{ result[column.metadata.colName] = column.value; } }); content.push(result); result = {}; }); // SQLのリクエスト完了時のイベントハンドラ。 // コネクションをクローズしないとDBにいらないプロセスが残るので、コネクションをクローズする。 request.on('requestCompleted', function(){ console.log('requestCompleted'); connection.close(); }); // DBへSQLを発行する。 connection.execSql(request); } });

下記のように、新しいコネクションと結果を入れるcontentを用意して、
1つめのSQLを実行後にくっつけてみましたがうまく動作しませんでした。

router.get('/', function(req, res, next) { var connection = new Connection(config); var content = []; // DBからselectした結果を格納する変数 // DB接続した際のイベントハンドラ connection.on('connect', function(err){ console.log("connected"); executeStatement(); }); // DB接続を終了した際のイベントハンドラ // DB接続を切断した後に画面を描写する connection.on('end', function(){ console.log("disconnected"); res.render('sample', { title: 'sqlserver-sample', content: content }); }); var Request = require('tedious').Request; // SQLを発行する関数 function executeStatement(){ // 発行するSQLを記載する request = new Request("SELECT * FROM TestDB.dbo.TB_TestTable with (NOLOCK)", function(err){ if(err){ console.log(err);} }); var result = {}; // SQLの結果を行ごとにオブジェクトに格納する。 // SQLの行ごとに実行するイベントハンドラ request.on('row', function(columns){ columns.forEach(function(column){ if(column.value === null){ console.log('NULL'); }else{ result[column.metadata.colName] = column.value; } }); content.push(result); result = {}; }); // SQLのリクエスト完了時のイベントハンドラ。 // コネクションをクローズしないとDBにいらないプロセスが残るので、コネクションをクローズする。 request.on('requestCompleted', function(){ console.log('requestCompleted'); connection.close(); }); // DBへSQLを発行する。 connection.execSql(request); } var connection2 = new Connection(config); var content2 = []; // DBからselectした結果を格納する変数 // DB接続した際のイベントハンドラ connection2.on('connect', function(err){ console.log("connected"); executeStatement(); }); // DB接続を終了した際のイベントハンドラ // DB接続を切断した後に画面を描写する connection2.on('end', function(){ console.log("disconnected"); res.render('sample', { title: 'sqlserver-sample', content: content }); }); var Request2 = require('tedious').Request; // SQLを発行する関数 function executeStatement(){ // 発行するSQLを記載する request2 = new Request("SELECT * FROM TestDB.dbo.TB_TestTable2 with (NOLOCK)", function(err){ if(err){ console.log(err);} }); var result = {}; // SQLの結果を行ごとにオブジェクトに格納する。 // SQLの行ごとに実行するイベントハンドラ request2.on('row', function(columns){ columns.forEach(function(column){ if(column.value === null){ console.log('NULL'); }else{ result[column.metadata.colName] = column.value; } }); content2.push(result); result = {}; }); // SQLのリクエスト完了時のイベントハンドラ。 // コネクションをクローズしないとDBにいらないプロセスが残るので、コネクションをクローズする。 request2.on('requestCompleted', function(){ console.log('requestCompleted'); connection2.close(); }); // DBへSQLを発行する。 connection2.execSql(request2); } });

調べても複数SQLを実行しているサンプルコードが見当たらず、質問させていただきました。
初歩的な質問で申し訳ございません。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

私もnodeは初心者なので自信ないのですが以下のようにしています。
同じことやってる方いたら私も教えてほしいです、、、

・SQLの実行部はfunctionに分けてrouter側では呼び出すだけにする
→返り値はpromiseにしてthenで結果を受け取る
・複数実行する場合はPromise.allで全て受け取る

私は全てストアドプロシージャを作成して実行するようにしていますので
ちょっとコードが変かもしれません、、、

sqlserver.js(sqlの実行部)

javascript

1var Request = require('tedious').Request; 2 3module.exports = function(storedproc, params, conn) { 4 //console.log(params); 5 if (params.length !== 0) { 6 storedproc += 7 ' ' + 8 params 9 .map(function(e) { 10 if (e.value == 'null' || e.value == null) return 'null'; 11 var v = ''; 12 13 switch (typeof e.value) { 14 case 'number': 15 v = e.value; 16 break; 17 default: 18 v = "'" + e.value + "'"; 19 } 20 return v; 21 }) 22 .join(','); 23 } 24 return new Promise(function(resolve, reject) { 25 conn.on('connect', function(err1) { 26 if (err1) { 27 console.log(err1); 28 reject(err1); 29 } 30 var request = new Request(storedproc, function(err) { 31 if (err) { 32 console.log(err); 33 reject(err); 34 } 35 }); 36 var res = []; 37 request.on('row', function(columns) { 38 var obj = {}; 39 for (var j = 0; j < columns.length; j++) { 40 obj[columns[j].metadata.colName] = columns[j].value; 41 } 42 res.push(obj); 43 }); 44 45 request.on('requestCompleted', function() { 46 resolve(res); 47 conn.close(); 48 }); 49 conn.execSql(request); 50 }); 51 /*conn.on("end", function() { 52 console.log("end"); 53 });*/ 54 conn.on('error', function(err) { 55 console.log(err); 56 }); 57 }); 58}; 59

router(実際の使い方)

javascript

1var express = require('express'); 2var router = express.Router(); 3 4var sqlserver = require('../functions/sqlserver'); 5 6/* GET home page. */ 7router.get('/', function(req, res, next) { 8 /* 単発 9 var sql = sqlserver( 10 'ストアドA', 11 [], 12 require('../connection')() 13 ); 14 sql 15 // rowsに行データが入る 16 .then(function(rows) { 17 response.json({ status: 0, data: rows }); 18 }) 19 .catch(function(err) { 20 console.log('err'); 21 response.json({ status: 1 }); 22 }); 23 */ 24 25 /* 複数は配列に突っ込んでPromise.all */ 26 var arr = []; 27 arr.push( 28 sqlserver('ストアドA', [], require('../connection')()) 29 ); 30 arr.push(sqlserver('ストアドB', [], require('../connection')())); 31 arr.push(sqlserver('ストアドC', [], require('../connection')())); 32 33 //複数実行した場合はthenのコールバック内の引数が配列になるのでそれで受け取る 34 Promise.all(arr) 35 .then(function(responses) { 36 res.render('index', { 37 title: 'テスト', 38 A: responses[0], 39 B: responses[1], 40 C: responses[2] 41 }); 42 }) 43 .catch(function(err) { 44 console.log(err); 45 }); 46}); 47

投稿2019/08/14 02:53

sousuke

総合スコア3828

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miyawaki

2019/08/15 01:46 編集

ご回答ありがとうございます! また、お返事が遅くなり申し訳ございません。 いただいたソースを参考にさせていただき、無事に取得することができました。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問