如何从 Node.js 对 Oracle DB 执行多个 MERGE INTO 查询

How to execute multiple MERGE INTO query on Oracle DB from Node.js

我正在尝试 运行 MERGE INTO 在 Node.js 代码的 forEach 循环中查询 OracleDB。但只有第一个查询执行和所有其他失败。

代码:

assignedDeals.forEach(async deal => {
          let EXPECTED_DATE = null;
          let STATUS = null;
          let COMMENT = null;
      
      let stmt = `MERGE INTO SP_ASSIGNMENT USING dual ON (ID = ${deal.ID}) WHEN MATCHED THEN UPDATE  SET MODIFIED_DATE = current_timestamp `
      if (deal.STATUS) {
        stmt = stmt + `,STATUS = '${deal.STATUS}'`;
        STATUS = `'${deal.STATUS}'`;
      }
      if (deal.COMMENT) {
        stmt = stmt + `,COMMENT = '${deal.COMMENT}'`;
        COMMENT = `'${deal.COMMENT}'`;
      }
      if (deal.EXPECTED_DATE) {
        stmt = stmt + `,EXPECTED_DATE = '${deal.EXPECTED_DATE}'`;
        EXPECTED_DATE = `'${deal.EXPECTED_DATE}'`
      }
      
      stmt = stmt + `WHEN NOT MATCHED THEN INSERT (ID,STATUS,ASSIGNED_USER_ID,MODIFIED_DATE,ASSIGNED_RID,ASSIGNED_BY,EXPECTED_DATE,STATUS,COMMENT) 
      VALUES (${deal.ID},'${deal.ISASSIGNED}','${deal.USERID}',current_timestamp,${parseInt(deal.RID)},'${deal.ASSIGNED_BY}',${EXPECTED_DATE},${STATUS},${COMMENT})`;

      console.log(stmt);
      await connection.execute(stmt,{},{
        autoCommit: true
      });
    });

这是在 for 循环中执行多个查询的正确方法吗?

知道为什么它不执行下一个查询吗?

帮我解决这个问题我是 Node.js + Oracle DB 的新手。

回答我自己的问题,这样可以帮助其他有类似问题的人。

所以在研究我的问题并根据评论后我可以得出结论,通过绑定变量和 executeMany() 方法我们可以实现我们的目标。

第 1 步: 准备如下绑定参数:

    let binds = [];
    assignedDeals.forEach(deal => {
      binds.push({
        ID: deal.ID,
        USER_ID: deal.USERID,
        RID: parseInt(deal.ASSIGNED_ROLE_ID),
        ASSIGNED_BY: deal.ASSIGNED_BY,
        EXPECTED_DATE: deal.EXPECTED_DATE ? new Date(deal.EXPECTED_DATE) : null,
        STATUS: deal.STATUS ? deal.STATUS : null,
        COMMENT: deal.COMMENT ? deal.COMMENT : null,
        SDC_STATUS: deal.SDC_STATUS ? deal.SDC_STATUS : null,
        DELETED_ON: null
      })
    })

步骤 2: 准备 ExecuteManyOptions:

autoCommit --> 用于自动提交您的语句。

Boolean autoCommit If this property is true, then the transaction in the current connection is automatically committed at the end of statement execution.

The default value is false.

This property may be overridden in an execute()/executeMany() call.

bindDefs --> Bind defs 用于根据您的 table 定义指定类型和大小。

Object bindDefs The bindDefs object defines the bind variable types, sizes, and directions. This object is optional in some cases but it is more efficient to set it.

It should be an array or an object, depending on the structure of the binds parameter.

Each value in the bindDefs array or object should be an object containing the keys dir, maxSize, and type for one bind variable, similar to how execute()/executeMany() bind parameters are identified.

示例:

const options = {
          autoCommit: true,
          bindDefs: {
            ID: { type: oracledb.NUMBER },
            USER_ID: { type: oracledb.DB_TYPE_VARCHAR, maxSize: 20 },
            RID: { type: oracledb.DB_TYPE_NUMBER},
            ASSIGNED_BY: { type: oracledb.DB_TYPE_VARCHAR, maxSize: 20 },
            EXPECTED_DATE: { type: oracledb.DATE },
            STATUS: { type: oracledb.DB_TYPE_VARCHAR, maxSize: 100 },
            COMMENT: { type: oracledb.DB_TYPE_VARCHAR, maxSize: 200 },
            SDC_STATUS: { type: oracledb.DB_TYPE_VARCHAR, maxSize: 20 },
            DELETED_ON: { type: oracledb.DATE },
          }
        };

第 3 步: 准备您的声明:

const sql = `MERGE INTO SP_ASSIGNMENT USING dual ON (DELETED_ON IS NULL AND ID = :ID) 
WHEN MATCHED THEN UPDATE SET MODIFIED_DATE = current_timestamp ,STATUS = :STATUS, SDC_STATUS = :SDC_STATUS,COMMENT = :COMMENT,EXPECTED_DATE = :EXPECTED_DATE 
WHEN NOT MATCHED THEN INSERT (ID,USER_ID,MODIFIED_DATE,RID,ASSIGNED_BY,EXPECTED_DATE,STATUS,COMMENT,SDC_STATUS,DELETED_ON) 
VALUES (:ID,:USER_ID,current_timestamp,:RID,:ASSIGNED_BY,:EXPECTED_DATE,:STATUS,:COMMENT,:SDC_STATUS,:DELETED_ON)`;

Note: I prepare the above statement as per my requirements but it's very in based on update & insert a condition. You can modify as per yours.

第 4 步:最后一步 调用 executeMany() 并传递您的 SQL 语句并绑定参数和绑定选项。

result = await connection.executeMany(sql, binds, options);

所以按照上面4个步骤就可以在MERGE INTO statement.

中实现基于USING ON条件的更新或插入

希望这对其他人有帮助。