


Cause
Someone asked "How to use nodejs to access sql server?"
After searching for information, I found that there are two types of solutions, using third-party nodejs plug-ins: https://github.com/orenmazor/node-tds, Use the ADODB.ConnectionActiveX object.
Reference:
http://stackoverflow.com/questions/857670/how-to-connect-to-sql-server-database-from-javascript
http://stackoverflow.com/questions/ 4728385/connecting-to-a-remote-microsoft-sql-server-from-node-js
If you use ActiveX, nodejs will be omnipotent under Windows, similar to writing asp. How do they communicate? Have to give it a try
Through
Thoughts
Use nodejs to access ActiveX indirectly through cscript.exe (windows script process)
cscript can parse both jscript and vbscript scripts, so jscript development is undoubtedly chosen for the convenience of maintenance.
Reference: http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/cscript_overview.mspx?mfr=true
Problems to be solved
1. Cross-process communication
The new version of nodejs adds operations on child processes, so cross-process communication is not a problem.
http://nodejs.org/docs/latest/api/all.html#child_Processes
var util = require('util'),
exec = require('child_process').exec,
child;
child = exec('cat *.js bad_file | wc -l',
function (error, stdout, stderr) {
console.log('stdout: ' stdout);
console.log('stderr: ' stderr);
if (error !== null) {
console.log('exec error: ' error);
}
});
For example, we can get the output content of the console stdout!
2. ActiveX related to database access, ADODB.Connection
Reference: http://msdn.microsoft.com/en-us/library/windows/desktop/aa746471(v=vs. 85).aspx
var connection = new ActiveXObject("ADODB .Connection");
var result = 'ok';
try{
connection.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" params.accessfile);
connection.Execute(params.sql);
} catch(ex){
result = ex.message;
}
return {
result: result
};
connection.Open(connectionString), the connection string parameter can be set to access sql server.
Reference: http://www.connectionstrings.com/sql-server-2005
3. To facilitate maintenance, the cscript and nodejs scripts are merged, and typeof exports is used to determine the current operating environment.
4. Character encoding cscript code uses ascii encoding
Non-ascii characters are encoded with "uHHHH" Unicode.
5. Command line characters need to be escaped. Double quotes and percent signs have special meanings in the command line.
Parameter transfer uses base64 encoding to avoid conflicts
cscript environment MSXML2.DOMDocument can do base64 encoding and decoding
function base64Decode(base64){
var xmldom = new ActiveXObject("MSXML2.DOMDocument");
var adostream = new ActiveXObject("ADODB.Stream");
var temp = xmldom.createElement("temp");
temp.dataType = "bin.base64";
temp.text = base64;
adostream.Charset = "utf-8";
adostream.Type = 1; // 1=adTypeBinary 2=adTypeText
adostream.Open();
adostream.Write(temp.nodeTypedValue);
adostream.Position = 0;
adostream.Type = 2; // 1=adTypeBinary 2=adTypeText
var result = adostream.ReadText(-1); // -1=adReadAll
adostream.Close();
adostream = null;
xmldom = null;
return result;
}
Summary
Calling process
1. Create a child process, Pass the encoded parameters;
2. After the child process is processed, the data will be output to the console in JSON format; (the child process automatically ends)
3. Read the data from the console and execute the callback function.
Advantages
1. Enable nodejs to have the ability to access ActiveX objects;
2. Simple implementation, easy development and maintenance.
Disadvantages
1. Can only run on Windows platform;
2. Data encoding and decoding will consume more CPU;
3. Each call needs to create a sub-process and restart it connect. (Can be improved)
Summary
1. It has certain practicality;
2. The cross-process communication performance can continue to be explored.
Module code:
var Access = {
create: function(params){
var fso = new ActiveXObject("Scripting.FileSystemObject");
var result = 'ok';
if (!fso.FileExists(params.accessfile)){
var adoxcatalog = new ActiveXObject("ADOX.Catalog");
try {
adoxcatalog.Create("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" params.accessfile);
} catch(ex) {
result = ex.message;
return;
}
adoxcatalog = null;
} else {
result = 'exists';
}
return {
result: result
};
},
existsTable: function(params){
var connection = new ActiveXObject("ADODB.Connection");
var result = 'ok', exists = false;
try{
connection.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" params.accessfile);
var recordset = connection.OpenSchema(20/*adSchemaTables*/);
recordset.MoveFirst();
while (!recordset.EOF){
if (recordset("TABLE_TYPE") == "TABLE" && recordset("TABLE_NAME") == params.tablename){
exists = true;
break;
}
recordset.MoveNext();
}
recordset.Close();
recordset = null;
} catch(ex){
result = ex.message;
}
return {
"result": result,
"exists": exists
};
},
execute: function(params){
var connection = new ActiveXObject("ADODB.Connection");
var result = 'ok';
try{
connection.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" params.accessfile);
connection.Execute(params.sql);
} catch(ex){
result = ex.message;
}
return {
result: result
};
},
query: function(params){
var connection = new ActiveXObject("ADODB.Connection");
var result = 'ok', records = [];
try{
connection.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" params.accessfile);
var recordset = new ActiveXObject("ADODB.Recordset");
recordset.Open(params.sql, connection);
var fields = [];
var enumer = new Enumerator(recordset.Fields);
for (; !enumer.atEnd(); enumer.moveNext()){
fields.push(enumer.item().name);
}
recordset.MoveFirst();
while (!recordset.EOF) {
var item = {};
for (var i = 0; i var fieldname = fields[i];
item[fieldname] = recordset(fieldname).value;
}
records.push(item);
recordset.MoveNext();
}
recordset.Close();
recordset = null;
} catch(ex){
result = ex.message;
}
return {
result: result,
records: records
};
}
};
if (/^u/.test(typeof exports)){ // cscript
void function(){
//from http://tangram.baidu.com/api.html#baidu.json
var JSON = {
stringify: (function () {
/**
* Character table that needs to be escaped during string processing
* @private
*/
var escapeMap = {
"b": '\b',
"t": '\t',
"n": '\n',
"f": '\f',
"r": '\r',
'"' : '\"',
"\": '\\'
};
/**
* String serialization
* @private
*/
function encodeString(source) {
if (/["\x00-x1f]/.test(source)) {
source = source.replace(
/["\x00-x1f]/g,
function (match) {
var c = escapeMap[match];
if (c) {
return c;
}
c = match.charCodeAt();
return "\u00"
Math.floor(c / 16).toString(16)
(c % 16).toString(16);
});
}
return '"' source '"';
}
/**
* Array serialization
* @private
*/
function encodeArray(source) {
var result = ["["],
l = source.length,
preComma, i, item;
for (i = 0; i item = source[i];
switch (typeof item) {
case "undefined":
case "function":
case "unknown":
break;
default:
if(preComma) {
result.push(',');
}
result.push(JSON.stringify(item));
preComma = 1;
}
}
result.push("]");
return result.join("");
}
/**
* Handle zero padding when serializing dates
* @private
*/
function pad(source) {
return source }
/**
* Date serialization
* @private
*/
function encodeDate(source){
return '"' source.getFullYear() "-"
pad(source.getMonth() 1) "-"
pad(source.getDate()) "T"
pad(source.getHours()) ":"
pad(source.getMinutes()) ":"
pad(source.getSeconds()) '"';
}
return function (value) {
switch (typeof value) {
case 'undefined':
return 'undefined';
case 'number':
return isFinite(value) ? String(value) : "null";
case 'string':
return encodeString(value).replace(/[^x00-xff]/g, function(all) {
return "\u" (0x10000 all.charCodeAt(0)).toString(16).substring(1);
});
case 'boolean':
return String(value);
default:
if (value === null) {
return 'null';
}
if (value instanceof Array) {
return encodeArray(value);
}
if (value instanceof Date) {
return encodeDate(value);
}
var result = ['{'],
encode = JSON.stringify,
preComma,
item;
for (var key in value) {
if (Object.prototype.hasOwnProperty.call(value, key)) {
item = value[key];
switch (typeof item) {
case 'undefined':
case 'unknown':
case 'function':
break;
default:
if (preComma) {
result.push(',');
}
preComma = 1;
result.push(encode(key) ':' encode(item));
}
}
}
result.push('}');
return result.join('');
}
};
})(),
parse: function (data) {
return (new Function("return (" data ")"))();
}
}
//http://blog.csdn.net/cuixiping/article/details/409468
function base64Decode(base64){
var xmldom = new ActiveXObject("MSXML2.DOMDocument");
var adostream = new ActiveXObject("ADODB.Stream");
var temp = xmldom.createElement("temp");
temp.dataType = "bin.base64";
temp.text = base64;
adostream.Charset = "utf-8";
adostream.Type = 1; // 1=adTypeBinary 2=adTypeText
adostream.Open();
adostream.Write(temp.nodeTypedValue);
adostream.Position = 0;
adostream.Type = 2; // 1=adTypeBinary 2=adTypeText
var result = adostream.ReadText(-1); // -1=adReadAll
adostream.Close();
adostream = null;
xmldom = null;
return result;
}
WScript.StdOut.Write('
var method = Access[WScript.Arguments(0)];
var result = null;
if (method){
result = method(JSON.parse(base64Decode(WScript.Arguments(1))));
}
WScript.StdOut.Write(JSON.stringify(result));
WScript.StdOut.Write('
}();
} else { // nodejs
void function(){
function json4stdout(stdout){
if (!stdout) return;
var result = null;
String(stdout).replace(/
result = JSON.parse(arguments[1]);
});
return result;
}
var util = require('util'), exec = require('child_process').exec;
for (var name in Access){
exports[name] = (function(funcname){
return function(params, callback){
console.log([funcname, params]);
exec(
util.format(
'cscript.exe /e:jscript "%s" %s "%s"', __filename,
funcname,
(new Buffer(JSON.stringify(params))).toString('base64')
),
function (error, stdout, stderr) {
if (error != null) {
console.log('exec error: ' error);
return;
}
console.log('stdout: ' stdout);
callback && callback(json4stdout(stdout));
}
);
}
})(name);
}
}();
}
调用代码:
var access = require('./access.js');
var util = require('util');
var accessfile = 'demo.mdb';
access.create({ accessfile: accessfile }, function(data){
console.log(data);
});
access.existsTable({ accessfile: accessfile, tablename: 'demo' }, function(data){
if (data.result == 'ok' && !data.exists){
access.execute({
accessfile: 'demo.mdb',
sql: "CREATE TABLE demo(id Counter Primary key, data Text(100))"
});
}
});
access.execute({
accessfile: 'demo.mdb',
sql: util.format("INSERT INTO demo(data) VALUES('zswang 路过!%s')", new Date)
}, function(data){
console.log(data);
});
access.query({
accessfile: 'demo.mdb',
sql: "SELECT * FROM demo"
}, function(data){
console.log(data);
});
最新代码:http://code.google.com/p/nodejs-demo/source/browse/#svn/trunk/database

Vercel是什么?本篇文章带大家了解一下Vercel,并介绍一下在Vercel中部署 Node 服务的方法,希望对大家有所帮助!

gm是基于node.js的图片处理插件,它封装了图片处理工具GraphicsMagick(GM)和ImageMagick(IM),可使用spawn的方式调用。gm插件不是node默认安装的,需执行“npm install gm -S”进行安装才可使用。

今天跟大家介绍一个最新开源的 javaScript 运行时:Bun.js。比 Node.js 快三倍,新 JavaScript 运行时 Bun 火了!

在nodejs中,lts是长期支持的意思,是“Long Time Support”的缩写;Node有奇数版本和偶数版本两条发布流程线,当一个奇数版本发布后,最近的一个偶数版本会立即进入LTS维护计划,一直持续18个月,在之后会有12个月的延长维护期,lts期间可以支持“bug fix”变更。

大家都知道 Node.js 是单线程的,却不知它也提供了多进(线)程模块来加速处理一些特殊任务,本文便带领大家了解下 Node.js 的多进(线)程,希望对大家有所帮助!

node怎么爬取数据?下面本篇文章给大家分享一个node爬虫实例,聊聊利用node抓取小说章节的方法,希望对大家有所帮助!


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

SAP NetWeaver Server Adapter for Eclipse
Integrate Eclipse with SAP NetWeaver application server.

Dreamweaver CS6
Visual web development tools

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

WebStorm Mac version
Useful JavaScript development tools

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.