无法使用 Node.js 使用 executeMany() 插入 Oracle DB
Unable to insert using executeMany() into Oracle DB with Node.js
我正在尝试通过 Node JS 将数据插入 Oracle 数据库。我正在从 Rest API 接收数据。我在 运行 代码 -
时遇到错误
Error: NJS-005: invalid value for parameter 2
这是我的 JSON 数据来自 API -
[{ "id": 6, "type": "LOOKUP_ID", "value": "A", "description": "Access Group A", "instime": "2016-06-30", "updtime": null, "deltime": null, "insuser": "ADMIN", "upduser": null, "deluser": null },
{ "id": 5, "type": "LOOKUP_ID", "value": "B", "description": "Access group for B", "instime": "2016-03-07", "updtime": null, "deltime": null, "insuser": "ADMIN", "upduser": null, "deluser": null },
{ "id": 7, "type": "LOOKUP_ID", "value": "C", "description": "Access Group for C", "instime": "2017-07-11", "updtime": null, "deltime": null, "insuser": "ADMIN", "upduser": null, "deluser": null },
{ "id": 10, "type": "LOOKUP_ID", "value": "M", "description": "Access Group for M", "instime": "2018-02-28", "updtime": null, "deltime": null, "insuser": "ADMIN", "upduser": null, "deluser": null }];
这是我的 Node JS 代码 -
'use strict';
const oracledb = require('oracledb');
const express = require('express');
var request = require("request")
const app = express();
app.get('/', (req, res) => {
oracledb.getConnection(
{
user: 'uid',
password: 'passwd',
connectString:
'(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=dbhost)(PORT=1521)(SEND_BUF_SIZE=)(RECV_BUF_SIZE=))(LOAD_BALANCE=yes))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=dbhost)))',
},
connExecute
);
function connExecute(err, connection) {
if (err) {
console.error(err.message);
res.send(err.message);
return;
}
var url = "http://localhost:8080/api/employees"
request({
url: url,
json: true
}, async function (error, response, body) {
try {
if (!error && response.statusCode === 200) {
const data = JSON.stringify(body);
const sql = `INSERT INTO TABLE
(ID, TYPE, VALUE, DESCR, INS, UPD, DELE, USER_INS, USER_UPD, USER_DELE)
VALUES
(:id, :type, :value, :description, :instime, :updtime,
:deltime, :insuser, :upduser, :deluser )`;
const binds = data;
const options = {
autoCommit: true,
bindDefs: {
id: { type: oracledb.NUMBER },
type: { type: oracledb.STRING, maxSize: 50 },
value: { type: oracledb.STRING, maxSize: 100 },
description: { type: oracledb.STRING, maxSize: 200 },
instime: { type: oracledb.DATE },
updtime: { type: oracledb.DATE },
deltime: { type: oracledb.DATE },
insuser: { type: oracledb.STRING, maxSize: 255 },
upduser: { type: oracledb.STRING, maxSize: 255 },
deluser: { type: oracledb.STRING, maxSize: 255 }
}
};
const result = await connection.executeMany(sql, binds, options);
console.log(result.rowsAffected);
}
} catch (error) {
console.log(error.message);
}
})
}
function connRelease(connection) {
connection.close(function (err) {
if (err) {
console.error(err.message);
}
});
}
});
const PORT = process.env.PORT || 8000;
app.listen(PORT, () => {
console.log(`App listening on port ${PORT}`);
console.log('Press Ctrl+C to quit.');
});
module.exports = app;
这是我的 Table 结构 -
我无法弄清楚我在这里做错了什么。需要一些帮助来解决这个问题。
您收到该错误是因为您在将绑定传递给 executeMany
之前对其进行了字符串化。 executeMany
需要一个 JS 数组,而不是字符串作为第二个参数。
其他几件事...每次收到请求时您都在创建一个数据库连接。这不会扩展。您需要创建连接池,然后从池中获取连接。
我看到了嵌套回调和 async/await 组合。我建议始终使用 async/await 除非你被迫使用回调(API 不支持承诺)。这将大大简化代码。
有关使用 Node.js 和 Oracle 数据库创建 REST API 的更多信息,请参阅本系列:
https://jsao.io/2018/03/creating-a-rest-api-with-node-js-and-oracle-database/
除了已经指出的不正确的字符串化之外,您将 "2016-06-30"
之类的字符串绑定为 oracledb.DATE
类型,因此您将收到错误。
有多种解决方法,但如果您的日期来自外部来源,则绑定为 oracledb.STRING
并确保数据库知道期望的日期格式可能更容易。这是一个工作示例:
'use strict';
process.env.NLS_LANG='.AL32UTF8';
process.env.NLS_DATE_FORMAT='YYYY-MM-DD';
process.env.ORA_SDTZ = 'UTC';
const oracledb = require('oracledb');
const config = require('./dbconfig.js');
async function run() {
let connection;
try {
connection = await oracledb.getConnection(config);
const sql = `INSERT INTO MTABLE
(ID, TYPE, VALUE, DESCR, INS, UPD, DELE, USER_INS, USER_UPD, USER_DELE)
VALUES
(:id, :type, :value, :description, :instime, :updtime, :deltime, :insuser, :upduser, :deluser )`;
const data = [
{ "id": 6, "type": "LOOKUP_ID", "value": "A", "description": "Access Group A", "instime": "2016-06-30", "updtime": null, "deltime": null, "insuser": "ADMIN", "upduser": null, "deluser": null },
{ "id": 5, "type": "LOOKUP_ID", "value": "B", "description": "Access group for B", "instime": "2016-03-07", "updtime": null, "deltime": null, "insuser": "ADMIN", "upduser": null, "deluser": null },
{ "id": 7, "type": "LOOKUP_ID", "value": "C", "description": "Access Group for C", "instime": "2017-07-11", "updtime": null, "deltime": null, "insuser": "ADMIN", "upduser": null, "deluser": null },
{ "id": 10, "type": "LOOKUP_ID", "value": "M", "description": "Access Group for M", "instime": "2018-02-28", "updtime": null, "deltime": null, "insuser": "ADMIN", "upduser": null, "deluser": null }
];
const options = {
autoCommit: true,
bindDefs: {
id: { type: oracledb.NUMBER },
type: { type: oracledb.STRING, maxSize: 50 },
value: { type: oracledb.STRING, maxSize: 100 },
description: { type: oracledb.STRING, maxSize: 200 },
instime: { type: oracledb.STRING, maxSize: 10 },
updtime: { type: oracledb.STRING, maxSize: 10 },
deltime: { type: oracledb.STRING, maxSize: 10 },
insuser: { type: oracledb.STRING, maxSize: 255 },
upduser: { type: oracledb.STRING, maxSize: 255 },
deluser: { type: oracledb.STRING, maxSize: 255 }
}
};
let result = await connection.executeMany(sql, data, options);
console.log(result);
} catch (err) {
console.error(err);
} finally {
if (connection) {
try {
await connection.close();
} catch (err) {
console.error(err);
}
}
}
}
run();
我正在尝试通过 Node JS 将数据插入 Oracle 数据库。我正在从 Rest API 接收数据。我在 运行 代码 -
时遇到错误Error: NJS-005: invalid value for parameter 2
这是我的 JSON 数据来自 API -
[{ "id": 6, "type": "LOOKUP_ID", "value": "A", "description": "Access Group A", "instime": "2016-06-30", "updtime": null, "deltime": null, "insuser": "ADMIN", "upduser": null, "deluser": null },
{ "id": 5, "type": "LOOKUP_ID", "value": "B", "description": "Access group for B", "instime": "2016-03-07", "updtime": null, "deltime": null, "insuser": "ADMIN", "upduser": null, "deluser": null },
{ "id": 7, "type": "LOOKUP_ID", "value": "C", "description": "Access Group for C", "instime": "2017-07-11", "updtime": null, "deltime": null, "insuser": "ADMIN", "upduser": null, "deluser": null },
{ "id": 10, "type": "LOOKUP_ID", "value": "M", "description": "Access Group for M", "instime": "2018-02-28", "updtime": null, "deltime": null, "insuser": "ADMIN", "upduser": null, "deluser": null }];
这是我的 Node JS 代码 -
'use strict';
const oracledb = require('oracledb');
const express = require('express');
var request = require("request")
const app = express();
app.get('/', (req, res) => {
oracledb.getConnection(
{
user: 'uid',
password: 'passwd',
connectString:
'(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=dbhost)(PORT=1521)(SEND_BUF_SIZE=)(RECV_BUF_SIZE=))(LOAD_BALANCE=yes))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=dbhost)))',
},
connExecute
);
function connExecute(err, connection) {
if (err) {
console.error(err.message);
res.send(err.message);
return;
}
var url = "http://localhost:8080/api/employees"
request({
url: url,
json: true
}, async function (error, response, body) {
try {
if (!error && response.statusCode === 200) {
const data = JSON.stringify(body);
const sql = `INSERT INTO TABLE
(ID, TYPE, VALUE, DESCR, INS, UPD, DELE, USER_INS, USER_UPD, USER_DELE)
VALUES
(:id, :type, :value, :description, :instime, :updtime,
:deltime, :insuser, :upduser, :deluser )`;
const binds = data;
const options = {
autoCommit: true,
bindDefs: {
id: { type: oracledb.NUMBER },
type: { type: oracledb.STRING, maxSize: 50 },
value: { type: oracledb.STRING, maxSize: 100 },
description: { type: oracledb.STRING, maxSize: 200 },
instime: { type: oracledb.DATE },
updtime: { type: oracledb.DATE },
deltime: { type: oracledb.DATE },
insuser: { type: oracledb.STRING, maxSize: 255 },
upduser: { type: oracledb.STRING, maxSize: 255 },
deluser: { type: oracledb.STRING, maxSize: 255 }
}
};
const result = await connection.executeMany(sql, binds, options);
console.log(result.rowsAffected);
}
} catch (error) {
console.log(error.message);
}
})
}
function connRelease(connection) {
connection.close(function (err) {
if (err) {
console.error(err.message);
}
});
}
});
const PORT = process.env.PORT || 8000;
app.listen(PORT, () => {
console.log(`App listening on port ${PORT}`);
console.log('Press Ctrl+C to quit.');
});
module.exports = app;
这是我的 Table 结构 -
我无法弄清楚我在这里做错了什么。需要一些帮助来解决这个问题。
您收到该错误是因为您在将绑定传递给 executeMany
之前对其进行了字符串化。 executeMany
需要一个 JS 数组,而不是字符串作为第二个参数。
其他几件事...每次收到请求时您都在创建一个数据库连接。这不会扩展。您需要创建连接池,然后从池中获取连接。
我看到了嵌套回调和 async/await 组合。我建议始终使用 async/await 除非你被迫使用回调(API 不支持承诺)。这将大大简化代码。
有关使用 Node.js 和 Oracle 数据库创建 REST API 的更多信息,请参阅本系列: https://jsao.io/2018/03/creating-a-rest-api-with-node-js-and-oracle-database/
除了已经指出的不正确的字符串化之外,您将 "2016-06-30"
之类的字符串绑定为 oracledb.DATE
类型,因此您将收到错误。
有多种解决方法,但如果您的日期来自外部来源,则绑定为 oracledb.STRING
并确保数据库知道期望的日期格式可能更容易。这是一个工作示例:
'use strict';
process.env.NLS_LANG='.AL32UTF8';
process.env.NLS_DATE_FORMAT='YYYY-MM-DD';
process.env.ORA_SDTZ = 'UTC';
const oracledb = require('oracledb');
const config = require('./dbconfig.js');
async function run() {
let connection;
try {
connection = await oracledb.getConnection(config);
const sql = `INSERT INTO MTABLE
(ID, TYPE, VALUE, DESCR, INS, UPD, DELE, USER_INS, USER_UPD, USER_DELE)
VALUES
(:id, :type, :value, :description, :instime, :updtime, :deltime, :insuser, :upduser, :deluser )`;
const data = [
{ "id": 6, "type": "LOOKUP_ID", "value": "A", "description": "Access Group A", "instime": "2016-06-30", "updtime": null, "deltime": null, "insuser": "ADMIN", "upduser": null, "deluser": null },
{ "id": 5, "type": "LOOKUP_ID", "value": "B", "description": "Access group for B", "instime": "2016-03-07", "updtime": null, "deltime": null, "insuser": "ADMIN", "upduser": null, "deluser": null },
{ "id": 7, "type": "LOOKUP_ID", "value": "C", "description": "Access Group for C", "instime": "2017-07-11", "updtime": null, "deltime": null, "insuser": "ADMIN", "upduser": null, "deluser": null },
{ "id": 10, "type": "LOOKUP_ID", "value": "M", "description": "Access Group for M", "instime": "2018-02-28", "updtime": null, "deltime": null, "insuser": "ADMIN", "upduser": null, "deluser": null }
];
const options = {
autoCommit: true,
bindDefs: {
id: { type: oracledb.NUMBER },
type: { type: oracledb.STRING, maxSize: 50 },
value: { type: oracledb.STRING, maxSize: 100 },
description: { type: oracledb.STRING, maxSize: 200 },
instime: { type: oracledb.STRING, maxSize: 10 },
updtime: { type: oracledb.STRING, maxSize: 10 },
deltime: { type: oracledb.STRING, maxSize: 10 },
insuser: { type: oracledb.STRING, maxSize: 255 },
upduser: { type: oracledb.STRING, maxSize: 255 },
deluser: { type: oracledb.STRING, maxSize: 255 }
}
};
let result = await connection.executeMany(sql, data, options);
console.log(result);
} catch (err) {
console.error(err);
} finally {
if (connection) {
try {
await connection.close();
} catch (err) {
console.error(err);
}
}
}
}
run();