使用Node.js连接SQL Server数据库

26

这个问题与一些旧问题重复,但自那时以来可能发生了一些变化。

是否有官方支持从Node.js连接到SQL Server的方式(例如来自MS的官方库)?或者至少有一些适用于生产级应用程序的维护良好的第三方库吗?

通常我们使用ASP.NET MVC / SQL Server组合,但目前我有一个任务,其中express / Node.js似乎更合适(而且我想尝试一些新东西),因此问题是我们是否可以依赖于Node.js和SQL Server之间的交互。

更新:看起来微软最终发布了官方驱动程序:https://github.com/WindowsAzure/node-sqlserver


我已经寻找这个问题的解决方案有几周了...感谢您添加这个问题。目前,我也正在使用一个轻量级MVC应用程序来处理SQL连接,但我不喜欢它。令人烦恼的是,我能找到的所有答案都指向同样不起作用的模块。 - Marcel Popescu
1
@MarcelPopescu,https://github.com/pekim/tedious 看起来对我来说可以工作,但有以下限制:它不支持事务(即使是存储过程中未明确发出但发生的事务),也不支持返回多个结果集的过程。返回多个结果集的过程应该重新编写;但是在没有事务的情况下,Node.js + MSSQL 的使用仅限于简单的几乎透明的前端界面(谢天谢地,这正是我正在编写的)。 - penartur
2
@MarcelPopescu 实际上,微软刚刚发布了官方 MSSQL 驱动程序:https://github.com/WindowsAzure/node-sqlserver - penartur
顺便说一句,我越看它,就越不喜欢它。它似乎写得非常糟糕,并且没有考虑到节点生态系统(例如,他们实现了自己的连接池)。 - penartur
可能是Node.js和Microsoft SQL Server的重复问题。 - Zephyr was a Friend of Mine
7个回答

29

这主要是为了未来的读者。由于问题(至少是标题)关注于“从Node.js连接到SQL Server数据库”,我想谈谈有关“mssql”节点模块的内容。

目前,我们有一个稳定的 Microsoft SQL Server 驱动程序的 NodeJs 版本(“msnodesql”),可以在此处找到:https://www.npmjs.com/package/msnodesql。虽然它比任何其他节点模块更好地实现了与 Microsoft SQL Server 数据库的本机集成,但需要注意一些事情。

“msnodesql”需要在主机上安装一些先决条件(如 Python、VC++、SQL Native Client 等)。这使您的“node”应用程序“Windows”相关。如果您不介意基于 Windows 的部署,则使用“msnodesql”最佳。

另一方面,还有另一个名为“mssql”的模块(可在此处找到:https://www.npmjs.com/package/mssql),可以根据配置使用“tedious”或“msnodesql”。虽然此模块可能不如“msnodesql”全面,但它几乎解决了大部分需求。

如果您想开始使用“mssql”,我遇到了一个简单明了的视频,其中讲解了如何使用 NodeJs 连接到 Microsoft SQL Server 数据库,视频链接在此:https://www.youtube.com/watch?v=MLcXfRH1YzE

上述视频的源代码可在此处找到:http://techcbt.com/Post/341/Node-js-basic-programming-tutorials-videos/how-to-connect-to-microsoft-sql-server-using-node-js

以防万一,如果以上链接无法使用,我在此处包含了源代码:

var sql = require("mssql");

var dbConfig = {
    server: "localhost\\SQL2K14",
    database: "SampleDb",
    user: "sa",
    password: "sql2014",
    port: 1433
};

function getEmp() {
    var conn = new sql.Connection(dbConfig);
    
    conn.connect().then(function () {
        var req = new sql.Request(conn);
        req.query("SELECT * FROM emp").then(function (recordset) {
            console.log(recordset);
            conn.close();
        })
        .catch(function (err) {
            console.log(err);
            conn.close();
        });        
    })
    .catch(function (err) {
        console.log(err);
    });

    //--> another way
    //var req = new sql.Request(conn);
    //conn.connect(function (err) {
    //    if (err) {
    //        console.log(err);
    //        return;
    //    }
    //    req.query("SELECT * FROM emp", function (err, recordset) {
    //        if (err) {
    //            console.log(err);
    //        }
    //        else { 
    //            console.log(recordset);
    //        }
    //        conn.close();
    //    });
    //});

}

getEmp();

以上代码相当简单易懂。我们先定义dbConfig JS对象中的数据库连接参数,然后使用Connection对象连接到SQL Server。为了执行“SELECT”语句,在这种情况下,它使用Request对象,该对象在内部与Connection对象一起工作。代码解释了使用基于“promise”和“回调”两种方式的执行。

以上源代码仅解释了如何连接到SQL Server数据库并执行SELECT查询。您可以通过遵循“mssql”节点文档的文档轻松将其提升到下一级: https://www.npmjs.com/package/mssql

更新: 有一个新视频,使用纯Node.js REST标准(带有Microsoft SQL Server)进行CRUD操作,链接为:https://www.youtube.com/watch?v=xT2AvjQ7q9E。 这是一个很棒的视频,从头开始解释了所有内容(其中包含大量代码,将整个代码都解释/复制到此处可能不太合适)。


我使用node-mssql,它非常棒,源代码存储库为:https://github.com/patriksimek/node-mssql - Kalamarico
2
我已经按照这个做了,但是我一直收到“将sql.connection传递给构造函数”的错误提示。 - cleverpaul
你很棒。 - ANUBIS
这个答案是黄金。只需要进行一些新版本的修改。使用“sql.ConnectionPool”代替“sql.Connection”,并在“port: 1433”之后添加“trustServerCertificate: true,”。花了我三天时间,终于我的代码可以工作了。 :) - noobmaster

14

2
tsqlftw 似乎已经停止更新;node-mssql 已不再提供支持;tedious 依赖于 iconv,而 iconv 又使用了 node-waf,但是 node-waf 在 Windows 上不可用,所以现在看来我只能选择 tds。至少今天我已经成功使用它连接到了数据库,虽然还没有执行任何查询。 - penartur
1
顺便提一下,iconv 对于 tedious 只是可选的,所以目前我正在尝试使用 tedious(虽然还没有做什么严肃的事情)。 tds 对我来说不起作用:https://github.com/cretz/node-tds/issues/25 - penartur
1
我目前正在使用 tedious,但是当我有空闲时间时,我会尝试迁移到最近发布的来自 MS 的官方驱动程序:https://github.com/WindowsAzure/node-sqlserver - penartur
官方驱动程序似乎需要很多东西,包括Visual Studio - 所以似乎不能在Linux上运行(?!)。 Tedious有良好的文档和漂亮的事件模型。现在在Windows上使用Tedious(顺便说一句,它没有Truestedconnection)。 - Lior

7
我们刚刚发布了用于SQL Server连接的Node.JS预览驱动程序。您可以在此处找到它:介绍用于SQL Server的Microsoft Node.JS驱动程序
该驱动程序支持回调函数(这里,我们正在连接到本地SQL Server实例):
// Query with explicit connection
var sql = require('node-sqlserver');
var conn_str = "Driver={SQL Server Native Client 11.0};Server=(local);Database=AdventureWorks2012;Trusted_Connection={Yes}";

sql.open(conn_str, function (err, conn) {
    if (err) {
        console.log("Error opening the connection!");
        return;
    }
    conn.queryRaw("SELECT TOP 10 FirstName, LastName FROM Person.Person", function (err, results) {
        if (err) {
            console.log("Error running query!");
            return;
        }
        for (var i = 0; i < results.rows.length; i++) {
            console.log("FirstName: " + results.rows[i][0] + " LastName: " + results.rows[i][1]);
        }
    });
});

或者,你可以使用事件(这里,我们连接到 SQL Azure,也称为 Windows Azure SQL 数据库):

// Query with streaming
var sql = require('node-sqlserver');
var conn_str = "Driver={SQL Server Native Client 11.0};Server={tcp:servername.database.windows.net,1433};UID={username};PWD={Password1};Encrypt={Yes};Database={databasename}";

var stmt = sql.query(conn_str, "SELECT FirstName, LastName FROM Person.Person ORDER BY LastName OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY");
stmt.on('meta', function (meta) { console.log("We've received the metadata"); });
stmt.on('row', function (idx) { console.log("We've started receiving a row"); });
stmt.on('column', function (idx, data, more) { console.log(idx + ":" + data);});
stmt.on('done', function () { console.log("All done!"); });
stmt.on('error', function (err) { console.log("We had an error :-( " + err); });

如果您遇到任何问题,请在 Github 上提交一个问题: https://github.com/windowsazure/node-sqlserver/issues

1
+1(仍然活跃-耶!)但这如何帮助我们锁定到Visual Studio/.NET相关产品?你们的营销计划...让我感到困惑。 - Erik Reppen
1
你如何关闭数据库连接? - gjw80
很好的问题。连接是如何处理的? - Nathan Tregillus
open 返回的连接对象具有定义为 function (immediately, callback)close 函数,其中 immediately 是可选的。因此,在上面的第一个示例中,如果您希望在关闭之前完成任何操作,则会调用 conn.close(callback),或者调用 conn.close(true, callback) 立即关闭而不等待。 - Joel
3
请注意,您应该提到这个驱动程序仅适用于Windows操作系统,这一点非常重要。另外,在开始关于如何使用库的博客文章时没有提到NPM安装行是有些奇怪的。 - jcollum

2

有一个名为mssqlhelper的npm模块。

你可以通过npm i mssqlhelper将其安装到你的项目中。

连接并执行查询的示例:

var db = require('./index');

db.config({
    host: '192.168.1.100'
    ,port: 1433
    ,userName: 'sa'
    ,password: '123'
    ,database:'testdb'
});

db.query(
    'select @Param1 Param1,@Param2 Param2'
    ,{
         Param1: { type : 'NVarChar', size: 7,value : 'myvalue' }
         ,Param2: { type : 'Int',value : 321 }
    }
    ,function(res){
        if(res.err)throw new Error('database error:'+res.err.msg);
        var rows = res.tables[0].rows;
        for (var i = 0; i < rows.length; i++) {
            console.log(rows[i].getValue(0),rows[i].getValue('Param2'));
        }
    }
);

您可以在此处阅读更多相关信息:https://github.com/play175/mssqlhelper

:o)


4
谢谢你的回答,但是一个不到一个月、由单个开发者维护、包含中文注释的库并不能给人留下可靠的产品级库的印象。此外,从代码来看,这个 mssqlhelper 库似乎只是在先前相关问题中提到的 tds 库上添加了一层薄的封装。我想听听可靠的、良好维护的库(最好是来自微软本身),而不是那些对于已知库进行薄封装的东西。 - penartur
2
顺便说一下,似乎作者还窃取了TDS包(https://github.com/cretz/node-tds/tree/master/lib)的源代码用于他们的mssqlhelper,并假装*play175*是自己编写的。 - penartur

0

msnodesql对我非常有用。这里是一个示例:

var mssql = require('msnodesql'), 
    express = require('express'),
    app = express(),
    nconf = require('nconf')

nconf.env()
     .file({ file: 'config.json' });

var conn = nconf.get("SQL_CONN");   
var conn_str = "Driver={SQL Server Native Client 11.0};Server=server.name.here;Database=Product;Trusted_Connection={Yes}";

app.get('/api/brands', function(req, res){
    var data = [];
    var jsonObject = {};    

    mssql.open(conn_str, function (err, conn) {
        if (err) {
            console.log("Error opening the connection!");
            return;
        }
        conn.queryRaw("dbo.storedproc", function (err, results) {
        if(err) {
                   console.log(err);
                   res.send(500, "Cannot retrieve records.");
                }
       else {
             //res.json(results);

             for (var i = 0; i < results.rows.length; i++) {
                 var jsonObject = new Object()
                 for (var j = 0; j < results.meta.length; j++) { 

                    paramName = results.meta[j].name;
                    paramValue = results.rows[i][j]; 
                    jsonObject[paramName] = paramValue;

                    }
                    data.push(jsonObject);  //This is a js object we are jsonizing not real json until res.send             
            } 

                res.send(data);

            }       
        });
    });
});

0

安装 mssqlexpress 模块以执行此程序

$ npm install express mssql

这个例子将允许您连接到 SQL Server 并从数据库中操作数据

const sql = require("mssql");

const express = require("express");

const app = express();

app.get("/", (req, res) => {

    const config = {
        user: "<your_username>",
        password: "<your_password>",
        server: "<your_server_name>", //or ip address
        database: "<database_name>",
        options: {
            encrypt: true, // For secure connection
            trustServerCertificate: true,
        },
    };

    sql.connect(config, (err) => {
        if (err) {
            console.log(err);
        } else {
            console.log("{ db_Connected! }");
        }

        
        // Write queries here
        

    });
});


app.listen(4000, () => {
    console.log("app listening on port no:", 4000);
});

以下是编写查询的示例

// Query example
new sql.Request().query("SELECT * FROM <table_name>", (err, result) => {
     if (err) {
         console.log(err);
     } else {
         res.send(result);
         sql.close();
     }
 });

你的答案可以通过添加更多有关代码功能和如何帮助提问者的信息来改进。 - Tyler2P
你的回答可以通过添加更多关于代码功能和如何帮助提问者的信息来改进。 - Tyler2P

-2
//start the program
var express = require('express');
var app = express();

app.get('/', function (req, res) {

    var sql = require("mssql");

    // config for your database
    var config = {
        user: 'datapullman',
        password: 'system',
        server: 'localhost', 
        database: 'chat6' 
    };

    // connect to your database
    sql.connect(config, function (err) {

        if (err) console.log(err);

        // create Request object
        var request = new sql.Request();

        // query to the database and get the records

        request.query("select * From emp", function (err, recordset) {            
            if  (err) console.log(err)

            // send records as a response
            res.send(recordset);

        });
    });
});

var server = app.listen(5000, function () {
    console.log('Server is running..');
});

//在数据库中创建一个名为emp的表(我已经创建了一个名为chat6的数据库)

// programs ends here

//将其保存为app.js并作为node app.js运行 //在浏览器中打开localhost:5000


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接