Access 데이터베이스를 예로 들어 nodejs를 사용하여 ActiveX 개체에 액세스합니다. _자바스크립트 기술

WBOY
풀어 주다: 2016-05-16 17:58:30
원래의
2272명이 탐색했습니다.

원인
누군가 "nodejs를 사용하여 SQL Server에 액세스하는 방법은 무엇입니까?"라고 물었습니다.
정보를 검색한 결과 타사 nodejs 플러그인을 사용하는 두 가지 유형의 솔루션이 있음을 발견했습니다: 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를 사용하면 asp를 작성하는 것과 유사하게 nodejs가 Windows에서 전능해집니다. 그들은 어떻게 의사소통을 하나요?

생각을 통해
노드JS를 사용하여 cscript.exe(Windows 스크립트 프로세스)를 통해 간접적으로 ActiveX에 액세스합니다.
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: ' error)
}
});
예를 들어 콘솔 stdout의 출력 콘텐츠를 얻을 수 있습니다!


2. 데이터베이스 접근 관련 ActiveX, ADODB.Connection
참고: http://msdn.microsoft.com/en-us/library/windows/desktop/aa746471(v=vs 85).aspx


var 연결 = new ActiveXObject("ADODB .Connection");
var result = 'ok';
try{
connection.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" params.accessfile) ;
연결.Execute(params.sql);
} catch(ex){
result = ex.message;
}
return {
결과: 결과
} ;


connection.Open(connectionString), 연결 문자열 매개변수는 SQL Server에 액세스하도록 설정할 수 있습니다.
참조: http://www.connectionstrings.com/sql-server-2005
3. 유지 관리를 용이하게 하기 위해 cscript와 nodejs 스크립트를 병합하고 typeof 내보내기를 사용하여 현재 운영 환경을 결정합니다.
4. 문자 인코딩 cscript 코드는 ASCII 인코딩을 사용합니다.
ASCII가 아닌 문자는 "uHHHH" 유니코드로 인코딩됩니다.
5. 명령줄 문자는 이스케이프 처리되어야 합니다. 큰따옴표와 백분율 기호는 명령줄에서 특별한 의미를 갖습니다.
매개변수 전송은 충돌을 피하기 위해 base64 인코딩을 사용합니다
cscript 환경 MSXML2.DOMDocument는 base64 인코딩 및 디코딩을 수행할 수 있습니다


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;
}

요약
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 결과 = '확인';
if (!fso.FileExists(params.accessfile)){
var adoxcatalog = new ActiveXObject("ADOX.Catalog");
시도해 보세요 {
adoxcatalog.Create("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" params.accessfile);
} catch(ex) {
result = ex.message;
반환;
}
adoxcatalog = null;
} else {
결과 = '존재함';
}
return {
결과: 결과
};
},
existsTable: function(params){
var 연결 = new ActiveXObject("ADODB.Connection");
var 결과 = '확인', 존재 = false;
시도해 보세요{
connection.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" params.accessfile);
var recordset = 연결.OpenSchema(20/*adSchemaTables*/);
recordset.MoveFirst();
while (!recordset.EOF){
if (recordset("TABLE_TYPE") == "TABLE" && records("TABLE_NAME") == params.tablename){
exists = true;
휴식;
}
recordset.MoveNext();
}
recordset.Close();
레코드세트 = null;
} catch(ex){
result = ex.message;
}
return {
"결과": 결과,
"존재": 존재
};
},
실행: function(params){
var 연결 = new ActiveXObject("ADODB.Connection");
var 결과 = '확인';
시도해 보세요{
connection.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" params.accessfile);
connection.Execute(params.sql);
} catch(ex){
result = ex.message;
}
return {
결과: 결과
};
},
쿼리: function(params){
var 연결 = new ActiveXObject("ADODB.Connection");
var 결과 = '확인', 기록 = [];
시도해 보세요{
connection.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" params.accessfile);
var recordset = new ActiveXObject("ADODB.Recordset");
recordset.Open(params.sql, 연결);
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 < fields.length; i ){
var fieldname = fields[i];
항목[필드명] = 레코드세트(필드명).값;
}
records.push(항목);
recordset.MoveNext();
}
recordset.Close();
레코드세트 = null;
} catch(ex){
result = ex.message;
}
return {
결과: 결과,
기록: 기록
};
}
};
if (/^u/.test(수출 유형)){ // cscript
void function(){
//from http://tangram.baidu.com/api.html#baidu. json
var JSON = {
stringify: (함수 () {
/**
* 문자열 처리 중 이스케이프해야 하는 문자 테이블
* @private
*/
var escapeMap = {
"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,
함수(일치) {
var c = escapeMap[match];
if (c) {
return c;
}
c = match.charCodeAt()
return "\u00"
Math.floor (c/16).toString(16)
(c % 16).toString(16);
})
}
return '"' 소스 '"';
/**
* 배열 직렬화
* @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 "undefine":
case "function ":
case "unknown":
break;
기본값:
if(preComma) {
result.push(',');
}
result.push (JSON.stringify(항목));
preComma = 1;
}
}
result.push("]");
return result.join("");
}
/**
* 날짜를 직렬화할 때 제로 패딩 처리
* @private
*/
함수 패드(소스) {
반환 소스 < 10? '0' 출처: 출처;
}
/**
* 날짜 직렬화
* @private
*/
function encodeDate(source){
return '"' source.getFullYear() "-"
pad(source.getMonth() 1 ) "-"
pad(source.getDate()) "T"
pad(source.getHours()) ":"
pad(source.getMinutes()) ":"
패드 (source.getSeconds()) '"';
}
반환 함수(값) {
스위치(값 유형) {
case 'undefine':
return 'undefine';
case 'number':
return isFinite(value) ? 문자열(값) : "널";
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 (값 === null) {
return 'null';
}
if (배열 인스턴스 값) {
return encodeArray(값);
}
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(항목 유형) {
case 'undefine':
case 'unknown':
case 'function':
break;
기본값:
if (preComma) {
result.push(',');
}
preComma = 1;
result.push(encode(key) ':' encode(item));
}
}
}
result.push('}');
결과 반환.join('');
}
};
})(),
분석: function (data) {
return (new Function("return (" data ")"))();
}
}
//http://blog.csdn.net/cuixiping/article/details/409468
function base64Decode(base64){
var xmldom = new ActiveXObject("MSXML2 .DOM문서");
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(메서드){
result = method(JSON.parse(base64Decode(WScript.Arguments(1))));
}
WScript.StdOut.Write(JSON.stringify(결과));
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(' exec error: ' error);
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 데모(id 카운터 기본 키, 데이터 텍스트(100))"
})
}
}) ;
access.execute({
accessfile: 'demo.mdb',
sql: util.format("INSERT INTO 데모(데이터) VALUES('zswang 路过!%s')", new Date)
}, 함수(데이터){
console.log(데이터)
});
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
관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿