无法使用 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();