节点oracle全部或全部查询

时间:2017-11-10 02:05:39

标签: node.js oracle

我目前正在使用nodeJS Oracle library对远程数据库进行查询。

但是,似乎该库一次只能处理单个查询。

因此,例如CREATE TABLE test1 (example1 Number, example2 Number)和另一个查询CREATE TABLE test2 (example1 Number, example2 Number)分开工作,但当我尝试

CREATE TABLE test1 (example1 Number, example2 Number)
CREATE TABLE test2 (example1 Number, example2 Number)

如下所示,它会抛出Error: ORA-00922: missing or invalid option

regular:function (oracledb, connectionConfig, successHandler, errorHandler) {
    /*
    * successHandler : function(result){}
    * errorHandler : function(error){}
    * */

    let userId = connectionConfig.userId;
    let password = connectionConfig.password;
    let host = connectionConfig.ip;
    let port = connectionConfig.port;
    let sid = connectionConfig.sid;
    let query = 'CREATE TABLE test1 (example1 Number, example2 Number)
CREATE TABLE test2 (example1 Number, example2 Number)'

    oracledb.getConnection(
        {
            user          : userId,
            password      : password,
            connectString : `(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = ${host})(PORT = ${port}))(CONNECT_DATA = (SID = ${sid})))`
        },
        function(err, connection)
        {
            if (err) {
                errorHandler(err);
                return;
            }
            connection.execute(
                query,
                function(err, result)
                {
                    if (err) {
                        errorHandler(err);
                        oracleFunctions.connection.doRelease(connection, errorHandler);
                        return;
                    }

                    successHandler(result);
                    oracleFunctions.connection.doRelease(connection, errorHandler);
                });
        });
},

仅供参考DataGrip查询。有没有办法确保只有在成功创建所有表时才创建多个表,但如果任何查询都不成功则会一起失败。

1 个答案:

答案 0 :(得分:1)

您可以使用SQL * Plus或SQLcl来执行脚本。请记住,您需要以分号结束语句:

CREATE TABLE test1 (example1 Number, example2 Number);
CREATE TABLE test2 (example1 Number, example2 Number);

或正斜杠(取决于你正在做什么):

CREATE TABLE test1 (example1 Number, example2 Number)
/
CREATE TABLE test2 (example1 Number, example2 Number)
/

在这种情况下,您可以使用其中一种,但不能同时使用两者。

以下是您在Node.js中使用的脚本示例:

const oracledb = require('oracledb');
const config = require('./dbConfig.js'); 
let conn;

async function multipleDDL() {
  try {
    conn = await oracledb.getConnection(config);

    let result;

    result = await conn.execute('create table t1 (c1 number, c2 number)');

    result = await conn.execute('create table t2 (c1 number, c2 number)');

    console.log('tables created successfully');
  } catch (err) {
    console.error(err);
  } finally {
    if (conn) {
      try {
        await conn.close();
      } catch (err) {
        console.error(err);
      }
    }
  }
}

multipleDDL();

以下是如何重写以使用带有EXECUTE IMMEDIATE的PL / SQL块来发出语句:

const oracledb = require('oracledb');
const config = require('./dbConfig.js'); 
let conn;

async function multipleDDL() {
  try {
    conn = await oracledb.getConnection(config);

    let result;

    result = await conn.execute(
     `begin
        execute immediate 'create table t1 (c1 number, c2 number)';
        execute immediate 'create table t2 (c1 number, c2 number)';
      end;`
    );

    console.log('tables created successfully');
  } catch (err) {
    console.error(err);
  } finally {
    if (conn) {
      try {
        await conn.close();
      } catch (err) {
        console.error(err);
      }
    }
  }
}

multipleDDL();

我相信可能有一种方法可以避免EXECUTE IMMEDIATE,但我必须深入研究(不确定解决方案有多简单)。

对于成功或失败的脚本,这是一个棘手的问题,因为在Oracle中,DDL发出隐式提交。不同的人根据情况使用不同的方法。这有两个选择:

  1. 您可以编写自己的“退出”脚本,并在出现问题时执行这些脚本。
  2. 我的一位同事建议,如果您对数据库拥有唯一控制权,则可以执行以下操作

    创建还原点X;

    //做DDL

    //中断了

    闪回数据库以恢复X点;