node 连接 oracledb 代码模块。
具体配置连接数据库方式,请看oracledb原文地址:https://www.npmjs.com/package/oracledb
windows的环境搭建:https://www.cnblogs.com/caiyt/p/10129710.html,Linux也需要配置,Linux的配置具体百度一下,网上很多。
gctx.js
//gctx.js
/**
* global context
* @type {{}}
*/
let gctx = {
/**
* 普通程序日志
*/
ERROR_CODE_RUN: '0',
/**
* 接口调用报错
*/
ERROR_CODE_API: '1',
/**
* 数据库执行报错(其实这个也算程序错误...)
*/
ERROR_CODE_DB: '2',
/**
* 程序错误
*/
ERROR_CODE_SYS: '3',
};
/**
* 全局封装的错误异常
* @param msg 问题描述
* @param code 问题代码
* @param param 导致问题的入参数据
* @returns {Error}{
* code//自定义错误编码
* message//消息
* file//具体错误位置
* }
*/
gctx.error = function (msg, code, param = null) {
let error = (new Error);
error.param = param;
error.code = common.isEmpty(code) ? gctx.ERROR_CODE_SYS : code;
error.message = msg;
error.file = error.stack.split('\n')[2];
return error;
};
/**
* 通用解析异常,并提取错误位置
* @param e
* @returns {string}
*/
gctx.parse = function (e) {
if (typeof (e) == "string") {
e = new Error(e);
}
if (e.code === undefined) {
e.code = gctx.ERROR_CODE_SYS;
}
let pos = null;
if (e.file === undefined) {
pos = e.stack.split('\n')[2];
e.file = pos;
} else {
pos = e.file;
}
e.msg = `错误提示:${e.message};`;
e.message = `${e.message}报错位置:${pos}`;
return e;
}
module.exports = gctx;
common.js
//文件模块
let fs = require('fs');
//文件解码模块
let iconv = require('iconv-lite');
//json long精度问题处理
var JSONstrict = require('json-bigint')({"storeAsString": true});
let common = {};
module.exports = common;
/************************************************通用功能辅助方法*********************************************************/
/**
* @description 判断是否非空
* @param obj
* @param checkObj 是否检查空对象
* @returns {boolean}
*/
common.isNotEmpty = function (obj, checkObj = false) {
if (obj === 0)//0需要特殊处理
{
return true;
}
if (checkObj) {
if (typeof (obj) == 'object' && obj !== null) {
//避免数组类对象
if (obj.constructor.name == 'Array') {
return obj.length != 0;
}
return (Object.keys(obj).length != 0);
}
if (Array.isArray(obj)) {
return obj.length != 0;
}
}
if (obj == null || obj == "null" || obj === "" || typeof (obj) == undefined || typeof (obj) == "undefined" || obj == "undefined" || typeof (obj) == null || typeof (obj) == "null") {
return false;
} else {
return true;
}
}
/**
* @description 判断是否为空
* @param obj
* @param checkObj 是否检查空对象
* @returns {boolean}
*/
common.isEmpty = function (obj, checkObj = false) {
return !common.isNotEmpty(obj, checkObj);
}
/**
* 替换对象属性的值,当值为空的时候,赋值空字符串
* */
common.replace_object_value = function (obj) {
let keys = Object.keys(obj);
for (let i = 0; i < keys.length; i++) {
if (common.isNotEmpty(obj[keys[i]]) == false) {
obj[keys[i]] = "";
}
}
}
/**删除数组中的某一个对象
_arr:数组
_obj:需删除的对象
*/
common.removeArray = function (_arr, _obj) {
let length = _arr.length;
for (let i = 0; i < length; i++) {
if (_arr[i] === _obj) {
if (i === 0) {
_arr.shift(); //删除并返回数组的第一个元素
return _arr;
} else if (i === length - 1) {
_arr.pop(); //删除并返回数组的最后一个元素
return _arr;
} else {
_arr.splice(i, 1); //删除下标为i的元素
return _arr;
}
}
}
}
/**
* 删除对象空属性
* */
common.removeObjectEmptyProperty = function (obj) {
//遍历对象属性
for (let key in obj) {
if (common.isNotEmpty(obj[key]) == false) {
delete obj[key];//删除空值的属性
}
}
}
/**************************************特殊字符处理模块*******************************************************************/
/**
* 计算分页
* total_count 总条数
* pageSize 每页条数
* 返回总页数
* */
common.CountPage = function (total_count, pageSize) {
total_count = parseInt(total_count);
pageSize = parseInt(pageSize);
return parseInt((total_count + pageSize - 1) / pageSize);
}
//获取六位随机数
common.r6 = function () {
return Math.random() * 900000 | 0 + 100000;
}
//获取n位随机数,随机来源chars
common.GetRandom = function (n) {
let chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
let res = "";
for (let i = 0; i < n; i++) {
let id = Math.ceil(Math.random() * (chars.length - 1));
res += chars[id];
}
return res;
}
/*获取请求客户的IP地址*/
common.IP = function (req) {
let ipAddress;
let headers = req.headers;
let forwardedIpsStr = headers['x-real-ip'] || headers['x-forwarded-for'];
forwardedIpsStr ? ipAddress = forwardedIpsStr : ipAddress = null;
if (!ipAddress) {
ipAddress = req.connection.remoteAddress;
}
return ipAddress;
}
//判断json对象是否存在属性字段
common.isEmptyObject = function (item) {
if (Object.keys(item).length == 0) {
return true;
}
return false;
}
//判断json对象是否存在属性字段
common.isNotEmptyObject = function (item) {
return !common.isEmptyObject(item);
}
/************************************************JSON功能辅助方法*********************************************************/
//把对象转化成字符串
common.JSON_stringify = function (data) {
// typeof 2 输出 number
// typeof null 输出 object
// typeof {} 输出 object
// typeof [] 输出 object
// typeof (function(){}) 输出 function
// typeof undefined 输出 undefined
// typeof '222' 输出 string
// typeof true 输出 boolean
if (typeof data != "string") {
return JSON.stringify(data);
}
return data;
}
//把字符串转化成对象
common.JSON_parse = function (data) {
try {
if (typeof data == "string") {
if (common.isNotEmpty(data) && common.stringHelper.isJSON(data)) {
return JSONstrict.parse(data);
}
return data;
} else {
return data;
}
} catch (err) {
throw err;//抛出异常
}
}
//JSON对象转化成数据
common.JSONToArray = function (data) {
let keys = Object.keys(data);
let array = [];
for (let i = 0; i < keys.length; i++) {
let id = keys[i];
array.push({id: id, name: data[id]});
}
array.sort((a, b) => a.id - b.id);//升序排序
return array;
}
//输出字符串
common.consoleLog = function () {
let position = (new Error).stack.split("\n")[2].trim();
let time = (new Date).toTimeString();
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
console.log(`时间:${time};位置:${position};`);
console.log(...arguments);
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
}
//输出字符串
common.consoleTitleLog = function (title, text) {
var position = (new Error).stack.split("\n")[2].trim();
var time = (new Date).toTimeString();
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
console.log(`时间:${time};位置:${position};`);
console.log(title, text);
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
}
/**
* 将true转化成1,false转化成0,原因为了适应oracle与mssql
* */
common.booleanToChar = function (value) {
if (value == true || value == "true") {
return 1;
} else {
return 0;
}
}
/**
* 将true转化成1,false转化成0,原因为了适应oracle与mssql
* */
common.charToBoolean = function (value) {
if (value == true || value == "true" || value == "1") {
return true;
} else {
return false;
}
}
/************************************************时间功能辅助方法*********************************************************/
//获取当前时间转日期字符串
common.nowtimeToDateStr = function () {
let now = new Date();
let year = now.getFullYear(), month = now.getMonth() + 1, day = now.getDate();
if (month < 10) {
month = "0" + month;
}
if (day < 10) {
day = "0" + day;
}
let datestr = year + "" + month + "" + day;
return datestr;
}
//获取当前时间转日期字符串
common.nowtimeToDatetimeStr = function () {
let now = new Date();
let year = now.getFullYear(),
month = now.getMonth() + 1,
day = now.getDate(),
hour = now.getHours(),
minute = now.getMinutes(),
second = now.getSeconds();
if (month < 10) {
month = "0" + month;
}
if (day < 10) {
day = "0" + day;
}
if (hour < 10) {
hour = "0" + hour;
}
if (minute < 10) {
minute = "0" + minute;
}
if (second < 10) {
second = "0" + second;
}
let datetimestr = year + "" + month + "" + day + "" + hour + "" + minute + "" + second;
return datetimestr;
}
//获取当前时间转日期字符串
common.nowtimeToDatetime = function () {
let now = new Date();
let year = now.getFullYear(),
month = now.getMonth() + 1,
day = now.getDate(),
hour = now.getHours(),
minute = now.getMinutes(),
second = now.getSeconds();
if (month < 10) {
month = "0" + month;
}
if (day < 10) {
day = "0" + day;
}
if (hour < 10) {
hour = "0" + hour;
}
if (minute < 10) {
minute = "0" + minute;
}
if (second < 10) {
second = "0" + second;
}
let datetimestr = year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
return datetimestr;
}
/**
* 将Date对象转化成字符串
* time 时间字符串
* format 输出时间格式
* */
common.formatTime = function (time, format) {
let t = new Date(time);
let tf = function (i) {
return (i < 10 ? '0' : '') + i
};
return format.replace(/yyyy|MM|dd|HH|mm|ss|S/g, function (a) {
switch (a) {
case 'yyyy':
return tf(t.getFullYear());
break;
case 'MM':
return tf(t.getMonth() + 1);
break;
case 'mm':
return tf(t.getMinutes());
break;
case 'dd':
return tf(t.getDate());
break;
case 'HH':
return tf(t.getHours());
break;
case 'ss':
return tf(t.getSeconds());
break;
case "S":
return tf(t.getMilliseconds());
break;
}
})
}
// 对Date的扩展,将 Date 转化为指定格式的String
// 月(M)、日(d)、小时(H)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,
// 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
// 例子:
// (new Date()).Format("yyyy-MM-dd HH:mm:ss.S") ==> 2006-07-02 08:09:04.423
// (new Date()).Format("yyyy-M-d HH:m:s.S") ==> 2006-7-2 8:9:4.18
Date.prototype.Format = function (fmt) { //author: meizz
let o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"H+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt))
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (let k in o)
if (new RegExp("(" + k + ")").test(fmt))
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
}
/**
* 时间戳转为时间
* timestamp 时间戳
* format 时间格式 yyyy-MM-dd HH:mm:ss
* */
common.GetTime = function (timestamp, format) {
if (common.isNotEmpty(timestamp) && timestamp != 0) {
let date = new Date(timestamp * 1000); //根据时间戳生成的时间对象
return common.formatTime(date, format);
} else {
return "";
}
}
/**
* DateTime时间格式转换为Unix时间戳格式
* date 时间字符串
* */
common.GetTimeStamp = function (date) {
return parseInt(new Date(date).getTime() / 1000);
}
/**
* 两个时间段的间隔
* 间隔天数 interval的值为1000*60*60*24
* 间隔分钟数 interval的值为1000*60
* @param startDate 开始时间字符串
* @param endDate 时间字符串
* @param interval 间隔时间
* @returns {number}
* @constructor
*/
common.GetDateDiff = function (startDate, endDate, interval) {
let startTime = new Date(Date.parse(startDate.replace(/-/g, "/"))).getTime();//获取毫秒数
let endTime = new Date(Date.parse(endDate.replace(/-/g, "/"))).getTime();//获取毫秒数
let time = parseInt(Math.abs((startTime - endTime)) / interval);
return time;
}
/**
* 比较时间大小,返回bool类型
* startDate 开始时间
* endDate 结束时间
* */
common.CompareDate = function (startDate, endDate) {
return new Date(startDate) < new Date(endDate)
}
/************************************************Cookie功能辅助方法*********************************************************/
//cookie转化
common.codeCookie = function (str) {
let strRtn = "";
for (let i = str.length - 1; i >= 0; i--) {
strRtn += str.charCodeAt(i);
if (i) strRtn += "a";
}
return strRtn;
}
//cookie反转化
common.decodeCookie = function (str) {
let strArr;
let strRtn = "";
strArr = str.split("a");
for (let i = strArr.length - 1; i >= 0; i--)
strRtn += String.fromCharCode(eval(strArr[i]));
return strRtn;
}
/*************************************数据库辅助方法******************************************************************/
//替换对象
common.replaceObject = function (item) {
let str = common.JSON_stringify(item);
str = str.replace(/'/g, "");
return common.JSON_parse(str);
}
//时间值转化为Oracle时间格式
common.replaceOracleTimeStr = function (text, format) {
if (common.isNotEmpty(text))
return "to_date('" + text + "','" + format + "')";
return null;
}
/**
* 时间条件语句
* jkpt_isOra 数据库是否为oracle数据库
* field 时间字段名称
* condition >= 或者<=
* time 值
* format js时间格式化yyyy-MM-dd HH:mm:ss
* oracleFormat oracle时间格式化写法:yyyy-mm-dd hh24:mi:ss
* */
common.returnTimeConditionSQL = function (jkpt_isOra, field, condition, time, format, oracleFormat) {
let where = "";
//判断是否有时间值
if (common.isNotEmpty(time)) {
if (jkpt_isOra) {
where = " and " + field + condition + " to_date('" + common.formatTime(time, format) + "','" + oracleFormat + "')";
} else {
where = " and " + field + condition + " '" + common.formatTime(time, format) + "'";
}
}
return where;
}
/**
* 当前时间修改语句
* jkpt_isOra 数据库是否为oracle数据库
* field 时间字段名称
* */
common.returnInsertTimeSQL = function (jkpt_isOra) {
let where = "";
//判断是否有时间值
if (jkpt_isOra) {
where = "sysdate ";
} else {
where = "getDate() ";
}
return where;
}
/**
* 返回时间执行语句
* jkpt_isOra 数据库是否为oracle数据库
* time 值
* format js时间格式化yyyy-MM-dd HH:mm:ss
* oracleFormat oracle时间格式化写法:yyyy-mm-dd hh24:mi:ss
* */
common.returnTimeExecSQL = function (jkpt_isOra, time, format, oracleFormat) {
let sql = null;
//判断是否有时间值
if (common.isNotEmpty(time)) {
if (jkpt_isOra) {
sql = " to_date('" + common.formatTime(time, format) + "','" + oracleFormat + "')";
} else {
sql = " '" + common.formatTime(time, format) + "'";
}
}
return sql;
}
/**
* 数组数据转化成查询语句 IN () 的数据
* list 数组字符串
* */
common.returnListExecINSQL = function (list) {
list = common.JSON_parse(list);
if (list.length == 0) {
return "";
}
let list_str = ""; //订单字符串
//遍历订单编号
for (let i = 0; i < list.length; i++) {
let id = list[i];
if (common.isNotEmpty(id)) {
list_str += "'" + list[i] + "',";
}
}
list_str = list_str.substr(0, list_str.length - 1);
return list_str;
}
/**
* 读取数据的时候,时间相差8个小时的处理,oracle的时间无需做处理,mssql的时间需要做处理
* jkpt_isOra 数据库是否为oracle数据库
* time 时间字段名称
* format js时间格式化yyyy-MM-dd HH:mm:ss
* */
common.returnTimeFromDBSelect = function (jkpt_isOra, time, format) {
//判断是否为oracle,是的话替换时间不同的处理方式
if (jkpt_isOra) {
return common.formatTime(time, format);
} else {
//数据库中获取的数据转换成json格式后,JS再取出来转换成时间,发现小时数多了8,原因和当地时区有关系,
// 解决办法形如:0001-01-01T00:00:00 可以用replace替换掉T。
let tempTime = common.JSON_stringify(time).replace("Z", "").replace("T", " ");
// common.consoleLog("CREATETIME:"+time);
// common.consoleLog("ReplaceCREATETIME:"+tempTime);
return common.formatTime(tempTime, "yyyy-MM-dd HH:mm:ss");
}
}
/*******************************************************************************************************/
/****************************************类型功能扩展**********************************************************/
/**
* 为string类型新增方法
* @returns {String}
*/
String.prototype.signMix = function () {
if (arguments.length === 0) return this;
let param = arguments[0], str = this;
if (typeof (param) === 'object') {
for (let key in param) {
let value = param[key];
value = value.toString().replace('$', '');
str = str.replace(new RegExp("\\{:" + key + "\\}", "g"), value);
//判断值是否等null是的话,直接给null
if (!(value === null)) {
value = "N'" + value + "'";
}
str = str.replace(new RegExp("\\{" + key + "\\}", "g"), value);
}
return str;
} else {
for (let i = 0; i < arguments.length; i++) {
// common.consoleLog (i+":"+ arguments[i]);
str = str.replace(new RegExp("\\{" + i + "\\}", "g"), arguments[i]);
}
return str;
}
}
String.prototype.trim = function () {
return this.replace(/^\s+|\s+$/g, '');
};
/**
* JSON对象中字符串的属性值拼接成字符串
* @param split_str 分隔符
* @returns {string}
*/
common.objectJoin = function (obj, split_str) {
let str = "";
for (let key in obj) {
if (typeof obj[key] == "string") {
str += obj[key] + split_str;
}
}
if (str != "")
str = str.substr(0, str.length - 1)
return str;
}
/****************************************文件读写功能**********************************************************/
//分割线
common.partition = "\r\n====================================================================================\r\n";
//结束分割线
common.endPartition = "\r\n***************************************************************************************\r\n";
/*******************保存日志***************************/
common.writeLog = async function (apiName, data) {
try {
let t = new Date();
let days = t.Format("yyyyMMdd");
await common.fileHelper.mkdirs('log');
fs.appendFileSync(`log/${apiName}_${days}_logs.txt`, `${data}${common.endPartition}`, function (err) {
if (err) {
console.error(err);
}
});
} catch (err) {
console.error(apiName, data, err);
}
}
/*******************读取整个JSON文件字符串***************************/
/*******************注意:文件的格式必须是UTF-8格式,可用txt文本做另存为UTF-8格式的文件***************************/
/*
* 读取 json文件
* file 文件的路径
* */
common.readFile = function readFile(file) {
//默认不用转码,默认是utf8的编码
// common.consoleLog (file)
let fileStr = fs.readFileSync(file, {encoding: 'utf8'});
if (fileStr == "")
return "";
// let buf = Buffer.from(fileStr,'utf8');
// fileStr = iconv.decode(buf,'utf8');
// common.consoleLog(fileStr);
let str = common.JSON_parse(fileStr);
// 获取里面的key
return str;
}
/*******************读取文件Json对象的某个字段***************************/
/*
* 读取 json文件 通过 key 获取对应的value
* */
common.readFileBykey = function (file, key) {
let str = common.readFile(file);
// 获取里面的key
return str[key];
}
/*******************修改文件Json对象的某个字段***************************/
/**
* 保存的字段
* file 文件路径
* key 要修改的key
* value 要保存的值
* */
common.writeFileBykey = function (file, key, value) {
try {
//默认不用转码,默认是utf8的编码
let fileStr = fs.readFileSync(file, {encoding: 'utf8'});
// let buf = Buffer.from(fileStr, 'utf8');
// let str = JSON.parse(iconv.decode(buf, 'utf8'));
// common.consoleLog (str);
// common.consoleLog("key:"+key +",value:"+value);
let str = common.JSON_parse(fileStr);
str[key] = value;
common.consoleLog(str);
fs.writeFileSync(file, common.JSON_stringify(str)); /// 写入
return true;
} catch (err) {
//写入日志
common.writeLog("writeFileBykey", file + err.message);
return false;
}
}
/**
* 保存的Json对象
* file 文件路径
* value 文件内容
* */
common.writeFile = function (file, value) {
try {
//默认不用转码,默认是utf8的编码
// //写入字符串转化成utf8编码,保证中文不会成乱码
// let buf = Buffer.from(value, 'utf8');
// common.consoleLog(buf);
// //字符串转化一下编码
// value = iconv.decode(buf, 'utf8');
// common.consoleLog(value);
// let str = JSON.parse(value);
fs.writeFileSync(file, common.JSON_stringify(value)); /// 写入
return common.returnResponse(true, "写入数据成功。");
} catch (err) {
//写入日志
common.writeLog("writeFile", file + err.message);
return common.returnResponse(false, err.message);
}
}
//对创建文件夹函数进行改装的函数随意路径没文件夹会自动创建(格式: 'web/upImg/images/mytest/'+_y + '/'+ _m + '/' + _d + "/")
common.MymkdirSync = function (url, mode, cb) {
common.consoleLog("url" + url);
let arr = url.split("/");
mode = mode || '0755';
cb = cb || function () {
};
if (arr[0] === ".") {//处理 ./aaa
arr.shift();
}
if (arr[0] == "..") {//处理 ../ddd/d
arr.splice(0, 2, arr[0] + "/" + arr[1])
}
function inner(cur) {
if (!fs.existsSync(cur)) {//不存在就创建一个
fs.mkdirSync(cur, mode);
}
if (arr.length) {
inner(cur + "/" + arr.shift());
} else {
cb();
}
}
arr.length && inner(arr.shift());
}
/**
* 等待多少毫秒后,才能执行下面的代码
* 这种实现方式是利用一个伪死循环阻塞主线程。因为JS是单线程的。所以通过这种方式可以实现真正意义上的sleep()。
* delay 毫秒时间
* */
common.sleep = function (delay) {
let start = (new Date()).getTime();
while ((new Date()).getTime() - start < delay) {
continue;
}
}
common.isArray = (array) => {
return Object.prototype.toString.call(array) === '[object Array]';
}
module.exports = common;
//导入oracledb模块 //基于版本@3.0.1 安装指令npm install oracledb
//node访问oracleDB需要搭建访问环境,否则无法正常访问
//创建Oracle对象
let oracledb;
let config = null;
let common_config = null;
/**
* 初始化配置参数
*/
function init_config() {
if (config == null) {
common_config = require("./config");
config = require("./config").oracle_config;
}
}
/**
* 初始化数据库对象
*/
function init() {
if (oracledb == null) {
try {
init_config();
//由于有些客户不是oracle数据库,由于oracle访问需要搭建环境,所以需要是oracle数据库才做模块的新建,否则项目会出错。
if (common_config.jkpt_isOra == 1) {
oracledb = require('oracledb');
//主要是这两行,在oracledb的文档中其实也有其它方法
//但是为了封装方法,采用如下方法统一处理
oracledb.fetchAsBuffer = [oracledb.BLOB];
oracledb.fetchAsString = [oracledb.CLOB];
}
} catch (err) {
console.log("oracledb声明错误原因:" + err.message);
}
}
}
let oracle = {};
//配置存储过程是的输出输入,与参数类型
oracle.db = oracledb;
let connection = null;
oracle.connection = null;
async function initConnection() {
if (connection == null) {
init();
connection = await oracledb.getConnection(config);//配置默认连接池,配置过就无需再继续配置
oracle.connection = connection;
common.consoleLog("初始化oracle数据库连接");
}
}
/**
* 初始化连接参数
* @param {string} user 用户名
* @param {string} password 密码
* @param {string} connectString 数据库连接字符串
*/
oracle.initConfig = async function (user, password, connectString) {
init_config();
if (user) {
config.user = user;
}
if (password) {
config.password = password;
}
if (connectString) {
config.connectString = connectString;
}
if (common.isEmpty(config.user) || common.isEmpty(config.password) || common.isEmpty(config.connectString)) {
throw gctx.error("oracle 连接参数为空!");
}
connection = null;
await initConnection();
}
//统计行号
let rowCount = 0;
/**
* 执行sql文本(带params参数),由于要使用逐条读取所以只能通过回调返回数据
* @param {string} sqlText 执行的sql语句
* @param {JSON} params sql语句中的参数
* @param {JSON} isToJson 每行都被提取为JavaScript对象
* @param {function} func 回调函数 逐行读取数据返回
*/
oracle.queryWithParams = async function (sqlText, params, isToJson, func) {
try {
let options = {resultSet: true, outFormat: oracledb.ARRAY};
if (isToJson) {
options = {resultSet: true, outFormat: oracledb.OBJECT};
}
//获取连接池内的连接
oracledb.getConnection(config,
function (err, connection) {
//判断是否存在异常信息,是释放数据库连接与返回错误信息
if (executeErr(err, connection, func)) {
return;
}
connection.execute(sqlText, params, options, async function (err, result) {
//判断是否存在异常信息,是释放数据库连接与返回错误信息
if (executeErr(err, connection, func)) {
return;
}
rowCount = 0;//初始化统计行号
fetchOneRowFromRS(connection, result.resultSet, func);
})
});
} catch (e) {
e = gctx.parse(e);
console.error(e);
return {state: false, data: e.message};//返回错误信息
}
};
//递归读取结果集的数据
function fetchOneRowFromRS(connection, resultSet, func) {
resultSet.getRow( // get one row
async function (err, row) {
if (err) {
console.error(err.message);
await doClose(connection, resultSet); // 发生异常错误的时候关闭数据库连接
} else if (!row) { // 无数据的时候,关闭数据库连接
await doClose(connection, resultSet);
} else {
rowCount++;
// common.consoleLog("fetchOneRowFromRS(): row " + rowCount);
// common.consoleLog(row);
func({state: true, data: row});//返回行数据
fetchOneRowFromRS(connection, resultSet, func);
}
});
}
/**
* 执行sql文本(带params参数)
* @param {string} sqlText 执行的sql语句
* @param {JSON} params sql语句中的参数
* let params = {
p1: 'Chris', // Bind type is determined from the data. Default direction is BIND_IN
p2: 'Jones',
ret: { dir: oracledb.BIND_OUT, type: oracledb.STRING, maxSize: 40 }
};
* @param {JSON} isToJson boolean类型 每行都被提取为JavaScript对象 ,
*/
oracle.queryByParams = async function (sqlText, params, isToJson) {
try {
await initConnection();//初始化连接
let options = {outFormat: oracledb.ARRAY};
if (isToJson) {
options = {outFormat: oracledb.OBJECT};
}
let result = await connection.execute(sqlText, params, options);
return {state: true, data: result};//返回查询的结果数据
} catch (e) {
console.error(e.message, sqlText);
e = gctx.parse(e);
await doReconnection(e.message, sqlText);
//判断数据库连接是否断开
if (VerifyConnection(e.message)) {
let result = oracle.queryByParams(sqlText, params, isToJson);
return result;
}
return {state: false, data: e.message};//返回错误信息
}
};
/**
* 执行存储过程文本(带params参数)
* @param {string} sqlText 执行的存储过程
* @param {JSON} params sql语句中的参数
* let params = {
p1: 'Chris', // Bind type is determined from the data. Default direction is BIND_IN
p2: 'Jones',
ret: { dir: oracledb.BIND_OUT, type: oracledb.STRING, maxSize: 40 }
};
* 查询结果的常量outFormat选项oracledb.ARRAY 4001 将每行作为列值数组获取,oracledb.OBJECT 4002 将每行作为对象获取
*/
oracle.executePro = async function (sqlText, params) {
try {
await initConnection();//初始化连接
let result = await connection.execute(sqlText, params, {outFormat: oracledb.ARRAY});
return {state: true, data: result};//返回存储过程执行结果数据
} catch (err) {
await doReconnection(err.message, sqlText);
//判断数据库连接是否断开
if (VerifyConnection(err.message)) {
let result = oracle.executePro(sqlText, params);
return result;
}
return {state: false, data: err.message};//返回错误信息
}
};
/**
* 执行一条数据插入,修改,删除,SQL语句(带params参数)
* @param {string} sqlText 执行SQL语句
* "INSERT INTO test VALUES (:id, :nm)",
* @param {JSON} params sql语句中的参数
* 写法一:{ id : {val: 1 }, nm : {val: 'Chris'} }
* 写法二:[1, 'Chris']
*/
oracle.execute = async function (sqlText, params) {
try {
await initConnection();//初始化连接
// common.consoleLog(sqlText);
let result = await connection.execute(sqlText, params, {autoCommit: true});
return {state: true, data: result};//返回执行结果数据
} catch (err) {
common.consoleLog(err);
await doReconnection(err.message, sqlText);
//判断数据库连接是否断开
if (VerifyConnection(err.message)) {
let result = oracle.execute(sqlText, params);
return result;
}
return {state: false, data: err.message};//返回错误信息
}
};
/**
* 执行多条数据插入,修改,删除,存储过程,文本(带params参数)
* @param {string} sqlText 执行的存储过程
* let sql = "INSERT INTO em_tab VALUES (:a, :b)";
* @param {JSON} params sql语句中的参数
* 写法一:let params = [
{ a: 1, b: "Test 1 (One)" },
{ a: 2, b: "Test 2 (Two)" },
{ a: 3, b: "Test 3 (Three)" },
{ a: 4 },
{ a: 5, b: "Test 5 (Five)" }
];
* 写法二:let params = [
[1, "Test 1 (One)"],
[2, "Test 2 (Two)"],
[3, "Test 3 (Three)"],
[4, null],
[5, "Test 5 (Five)"]
];
* @param {JSON} options sql语句中的参数
* 写法一: let options = {
autoCommit: true,//必须有这个自动提交参数
bindDefs:
[ { type: oracledb.NUMBER },
{ type: oracledb.STRING, maxSize: 15 }
] };
写法二:
let options = {
autoCommit: true,//必须有这个自动提交参数
bindDefs: {
a: { type: oracledb.NUMBER },
b: { type: oracledb.STRING, maxSize: 15 }
} };
*/
oracle.executeMany = async function (sqlText, params, options) {
options = Object.assign({}, options, {autoCommit: true});//默认配置执行语句自动提交
try {
await initConnection();//初始化连接
let result = await connection.executeMany(sqlText, params, options);
return {state: true, data: result};//返回执行结果数据
} catch (e) {
e = gctx.parse(e);
await doReconnection(e.message, sqlText);
console.error(e);
//判断数据库连接是否断开
if (VerifyConnection(e.message)) {
let result = oracle.executeMany(sqlText, params, options);
return result;
}
return {state: false, data: e.message};//返回错误信息
}
};
/**
* 验证数据库表是否存在
* tableName 表名
* 返回boolean类型,true或者false
* */
oracle.verifyHaveTable = async function (tableName) {
let select_sql = "select * from user_tables where table_name =upper('" + tableName + "')";
let result = await oracle.queryByParams(select_sql, [], true);
if (result.state) {
if (result.data.rows.length > 0) {
return true;
}
}
return false;
}
/**
* 验证数据库视图是否存在
* tableName 视图名称
* 返回boolean类型,true或者false
* */
oracle.verifyHaveViewTable = async function (tableName) {
let select_sql = "select * from user_views where VIEW_NAME =upper('" + tableName + "')";
let result = await oracle.queryByParams(select_sql, [], true)
if (result.state) {
if (result.data.rows.length > 0) {
return true;
}
}
return false;
}
//执行SQL语句错误回调函数释放数据库连接
function executeErr(err, connection, func) {
if (err) {
console.error(err.message);
doRelease_async(connection);//释放数据库连接
func({state: false, data: err.message});//返回错误信息
return true;
}
return false;
}
//关闭当前数据库连接
oracle.doClose = async function () {
if (connection) {
try {
await connection.close();
} catch (err) {
console.error(err.message);
}
}
}
//关闭数据库连接
function doRelease_async(connection) {
if (connection) {
connection.close(
function (err) {
if (err) {
console.error(err.message);
}
});
}
}
//重新连接数据库
async function doReconnection(message, sqlText) {
let time = new Date().Format("HH:mm:ss");
common.writeLog("oracle_connection", time + common.partition + sqlText + common.partition + message);
console.error(message);
//释放连接,重新连接oracle
if (VerifyConnection(message)) {
connection = null;//重新初始化oracle连接
await initConnection();//初始化连接
}
}
//关闭结果集在关闭数据库连接
async function doClose(connection, resultSet) {
try {
if (resultSet) {
await resultSet.close();//释放读取流
}
if (connection) {
await connection.close();//释放连接,将连接放回池中
}
} catch (err) {
console.error(err.message);
}
}
/**
* @description 验证数据库连接是否正常
* @param message
* @return {boolean}
* @constructor
*/
function VerifyConnection(message) {
// common.consoleLog("VerifyConnection:" + message);//输出错误信息
// console.error(message);
//释放连接,重新连接mssql
if (message.search("not connected to ORACLE") >= 0
|| message.search("invalid connection") >= 0
|| message.search("connection lost contact") >= 0
|| message.search("通信通道的文件结尾") >= 0
|| message.search("未连接到 ORACLE") >= 0) {
return true;
}
return false;
}
module.exports = oracle;
以上就是Nodejs oracledb详细解读的详细内容,更多关于Nodejs oracledb详细解读的资料请关注九品源码其它相关文章!