原因
誰かが「nodejs を使用して SQL サーバーにアクセスする方法は?」と質問しました。
情報を検索したところ、サードパーティの nodejs プラグインを使用する 2 種類のソリューションがあることがわかりました: https://github. com/orenmazor/node-tds、ADODB.ConnectionActiveX オブジェクトを使用します。
参考:
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
ActiveX を使用する場合、nodejs は、ASP を記述するのと同様に、Windows 上で全能になります。彼らはどのようにコミュニケーションをとっているのでしょうか?ぜひ試してみてください
スルー
思考
cscript.exe (Windows スクリプト プロセス) を通じて間接的に ActiveX にアクセスするには、nodejs を使用します
cscript は jscript スクリプトと vbscript スクリプトの両方を解析できるため、jscript 開発が選択されるのは間違いありませんメンテナンスの便宜のため。
参考: http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/cscript_overview.mspx?mfr=true
解決すべき問題
1.クロスプロセス通信
nodejs の新しいバージョンでは、子プロセスに対する操作が追加されるため、クロスプロセス通信は問題になりません。
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: ' エラー)
たとえば、コンソールの標準出力の出力内容を取得できます。
2. データベース アクセスに関する ActiveX、ADODB.Connection
参照: http://msdn.microsoft.com/en-us/library/windows/desktop/aa746471(v=vs) .85).aspx
コードをコピーします
connection.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" params.accessfile) ;
connection.Execute(params.sql);
} catch(ex){
result = ex.message;
return {
result: 結果
} ;
connection.Open(connectionString)、SQL サーバーにアクセスするための接続文字列パラメーターを設定できます。
参照: http://www.connectionstrings.com/sql-server-2005
3. メンテナンスを容易にするために、cscript スクリプトと nodejs スクリプトがマージされ、typeof エクスポートを使用して現在の動作環境が決定されます。
4. 文字エンコード cscript コードは ASCII エンコードを使用します。
非 ASCII 文字は「uHHHH」Unicode でエンコードされます。
5. コマンド ライン文字は、コマンド ラインでは特別な意味を持ちます。エスケープする必要があります。
パラメータ転送は競合を避けるために Base64 エンコードを使用します
cscript 環境 MSXML2.DOMDocument は Base64 エンコードとデコードを実行できます
コードをコピー
temp.dataType = "bin.base64";
temp.text =base64;
adostream.Charset = "utf-8";
adostream.Type = 1; // 1=adTypeBinary 2=adTypeText
adostream.Open(); >adostream.Position = 0;
adostream.Type = 2; // 1=adTypeBinary 2=adTypeText
var result = adostream.ReadText(-1); // -1=adReadAll
adostream.Close ();
adostream = null;
return result;
呼び出しプロセス
1.子プロセスを作成し、エンコードされたパラメータを渡します。
2. 子プロセスが処理されると、データが JSON 形式でコンソールに出力されます。
3.コンソールにアクセスしてコールバック関数を実行します。
利点
1. nodejs が ActiveX オブジェクトにアクセスできるようにします。
2. シンプルな実装、簡単な開発とメンテナンス。
欠点
1. Windows プラットフォームでのみ実行可能;
2. データのエンコードとデコードはより多くの CPU を消費します。
3.そして接続を再起動します。 (改善可能)
概要
1. 一定の実用性を備えています。
2. プロセス間通信のパフォーマンスを引き続き調査できます。
モジュール コード:
コードをコピー
コードは次のとおりです:
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) {
結果 = ex.message;
戻る;
}
adoxcatalog = null;
} else {
結果 = '存在';
}
return {
結果: 結果
};
},
existsTable: function(params){
var connection = new ActiveXObject("ADODB.Connection");
var 結果 = 'ok'、存在 = false;
try{
connection.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" params.accessfile);
var Recordset = connection.OpenSchema(20/*adSchemaTables*/);
レコードセット.MoveFirst();
while (!recordset.EOF){
if (recordset("TABLE_TYPE") == "TABLE" && Recordset("TABLE_NAME") == params.tablename){
exists = true;
休憩;
}
recordset.MoveNext();
}
recordset.Close();
レコードセット = null;
} catch(ex){
結果 = ex.message;
}
return {
"result": 結果、
"exists": 存在します
};
},
実行: 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){
結果 = ex.message;
}
return {
結果: 結果
};
},
クエリ: function(params){
var connection = new ActiveXObject("ADODB.Connection");
var 結果 = 'ok'、レコード = [];
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 フィールド = [];
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 フィールド名 = フィールド[i];
アイテム[フィールド名] = レコードセット(フィールド名).値;
}
records.push(item);
レコードセット.MoveNext();
}
recordset.Close();
レコードセット = null;
} catch(ex){
結果 = ex.message;
}
return {
結果: 結果,
レコード: レコード
};
}
};
if (/^u/.test(typeof exports)){ // cscript
void function(){
//http://tangram.baidu.com/api.html#baidu より。 json
var JSON = {
stringify: (function () {
/**
* 文字列処理中にエスケープする必要がある文字テーブル
* @private
*/
varscapeMap = {
"b": '\b',
"t": '\t'、
"n": '\n'、
"f": '\f'、
"r": '\r'、
' "' : '\"',
"\": '\\'
}
/**
* 文字列シリアル化
* @private
*/
function encodeString(source) {
if (/ ["\x00-x1f]/.test(source)) {
source = source.replace(
/["\x00-x1f]/g,
function (match) {
var c =scapeMap[match];
if (c) {
return c;
}
c = match.charCodeAt();
return "\u00"
(c / 16).toString(16)
(c % 16).toString(16)
}
ソース '"' を返します。
/**
* 配列のシリアル化
* @private
*/
function encodeArray(source) {
var result = ["["],
l = source.length,
preComma, i, item;
for (i = 0; i < l; i ) {
item = source[i];
switch (typeof item) {
case "未定義":
case "関数":
case "unknown":
break;
default:
if(preComma) {
result.push(',');
}
result.push (JSON.stringify(item));
プレカンマ = 1;
}
}
result.push("]");
return result.join("");
}
/**
* 日付をシリアル化するときにゼロパディングを処理します
* @private
*/
関数パッド(ソース) {
ソースを返す < 10? '0' ソース : ソース;
}
/**
* シリアル化日
* @private
*/
function encodeDate(source){
return '"' source.getFull Year() "-"
Pad(source.getMonth() 1 ) "-"
パッド(source.getDate()) "T"
パッド(source.getHours()) ":"
パッド(source.getMinutes()) ":"
パッド(source.getSeconds()) '"';
}
戻り関数 (値) {
スイッチ (値の型) {
ケース '未定義':
戻り '未定義';
case 'number':
return isFinite(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);
デフォルト:
if (value === null) {
return 'null';
}
if (配列の値インスタンス) {
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 '未定義':
case 'unknown':
case 'function':
break;
デフォルト:
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
functionbase64Decode(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;
結果を返します。
}
WScript.StdOut.Write('');
var メソッド = Access[WScript.Arguments(0)];
var 結果 = null;
if (メソッド){
結果 = メソッド(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 結果 = null;
String(stdout).replace(/([sS] )/, function(){
result = JSON.parse(arguments[1]);
} );
結果を返します。
}
var util = require('util'), exec = require('child_process').exec;
for (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('実行エラー: ' エラー);
return;
console.log('stdout: ' stdout);
callback && callback(json4stdout(stdout)); );
}
})(名前);
}
}();
}
调用代:
复制代
代码如下: 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 Demon(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 デモ"
}, function(data){
console.log(data);
});
最新代:
http://code.google.com/p/nodejs-demo/source/browse/#svn/trunk/database