NodeJS,Oracle DB参数的部分绑定给出:ORA-01036

Posted

技术标签:

【中文标题】NodeJS,Oracle DB参数的部分绑定给出:ORA-01036【英文标题】:NodeJS ,Partial binding of Oracle DB parameters gives : ORA-01036 【发布时间】:2018-08-28 19:30:08 【问题描述】:

我正在处理一项在某些表上有一些插入/更新的任务。

当我在插入/更新语句中使用表的完整列时,它对我有用 但是每当我只更新所需的列而忽略其余的未触及时,我都会面对 ORA-01036

我正在调用一个通用 Lambda 函数来传递查询和参数 成功场景:

"stage": "dev", "params": "id": 5956049, "groupName": "testtoberemoved123", "externalName": "Axiom_420K_Wheattest547", "description": "desc 123", "createdOn": "2018-08-27T22:00:00.000Z", "createdBy": "EOM", "updatedOn": "2018-08-28T16:16:41.207Z", "updatedBy": "EOM", "status": 1, "vendorID": null, "technologyCode": null , "query": "update assay_group set NAME=:groupName , EXTERNAL_NAME=:externalName, DESCRIPTION=:description ,CREATED_DATE=to_timestamp_tz( :createdOn, 'yyyy-mm-dd"T"hh24:mi:ss:ff3 TZH:TZM'),CREATED_USER=:createdBy ,LAST_UPDATED_DATE=to_timestamp_tz( :updatedOn, 'yyyy-mm-dd"T"hh24:mi:ss:ff3 TZH:TZM'),LAST_UPDATED_USER=:updatedBy ,GROUP_STATUS=:status,VENDOR_ID=:vendorID,TECHNOLOGY_CODE=:technologyCode where ID=:id", "enableObjectFormat": true, "options": "autoCommit": true

这个运行成功,但是当从语句中删除一些列时它会失败,如下所示:

"stage": "dev", "params": "id": 5956049, "groupName": "testtoberemoved123", "externalName": "Axiom_420K_Wheattest547", "description": "desc 123", "createdOn": "2018-08-27T22:00:00.000Z", "createdBy": "EOM", "updatedOn": "2018-08-28T16:09:36.215Z", "updatedBy": "EOM", "status": 3, "vendorID": null, "technologyCode": null , "query": "update assay_group set NAME=:groupName where ID=:id", "enableObjectFormat": true, "options": "autoCommit": true

这会导致以下错误: "errorMessage":"执行查询时出错 - ORA-01036: 非法变量名/编号\n",

通用执行器如下

`

'use strict';

var oracledb =  require("oracledb-for-lambda");
var dbConfig = require('./resources/dbConfig-dev.js');

module.exports.executeQuery= (event, context, callback) => 

  var maxSize = parseInt(process.env.maxRows, 10);

  // Extract enableJSONParse option
  var enableJSONParse = false;
  if(event.enableJSONParse != null && event.enableJSONParse != undefined) 
    enableJSONParse = event.enableJSONParse;
    console.log("enableJSONParse provided in event");
  
  console.log("Enable JSON Parse: " + enableJSONParse);

  // Extract options 
  var options = ;
  if(event.options != null && event.options != undefined) 
    options = event.options;
    console.log("options provided in event");
  
  // Add maxSize to options
  options.maxRows = maxSize;
  console.log("Options: " + JSON.stringify(options));

  // Set oracledb output format to object
  var enableObjectFormat = event.enableObjectFormat;
  console.log("Enable Object Format: " + enableObjectFormat);
  if(enableObjectFormat) 
    console.log("Object Format Enabled");
    oracledb.outFormat = oracledb.OBJECT;
   else 
    oracledb.outFormat = oracledb.ARRAY;
  
  console.log("oracledb.outFormat: " + oracledb.outFormat);

  var currentStage = event.stage;
  console.log("Current Stage: " + currentStage);

  if (currentStage != null && currentStage != 'undefined') 
      var configFileName = './resources/dbConfig-' + currentStage + '.js'  
    try
      dbConfig = require(configFileName);
     catch (error) 
      callback(new InternalServerError("No dbConfig found - " + error.message));
      return;
    
  
  console.log("Using dbConfig: " + JSON.stringify(dbConfig));

  var response = "";
  var parameters = event.params;
  var query =   event.query;

  if(query == null || query == undefined || query == "")  // Empty Query - throw error
    console.log("Missing required field - query")
    callback(new MissingRequiredFieldError("Missing Required Field - query"));
    return;
  

  if(parameters == null || parameters == undefined)  // parameters not provided in event - set to empty list
    console.log("No parameters defined");
    parameters = [];
  
  console.log("Query: " + query);
  console.log("Query Parameters: " + parameters);

    oracledb.getConnection(
  
    user          : dbConfig.user,
    password      : dbConfig.password,
    connectString  :dbConfig.connectString
  ,
  function(err, connection) 
    if (err) 
      console.error("Connection Error: " + err.message);
      callback(new InternalServerError("Error while connecting to database - "+ err.message));
      return;
    
     // return all CLOBs as Strings
    oracledb.fetchAsString = [ oracledb.CLOB ];

    connection.execute(
      // The statement to execute
      query, 
      parameters,     // Query Param
      options, // Options
      // The callback function handles the SQL execution results
      function(err, result) 
        if (err) 
          console.error("Execution Error Messages = " + err.message);
          doRelease(connection);
          callback(new InternalServerError("Error while executing query - "+ err.message));
          return;          
        
        console.log("Query " + query + " Executed Successfully");

        var resultSet;
        // In case query is SELECT
        if(result.rows != null && result.rows != undefined) 
          console.log("Returned rows: " + result.rows.length);
          console.log("Result.metaData: " + JSON.stringify(result.metaData)); 
          console.log("Result.rows: " + JSON.stringify(result.rows));           
          resultSet = result.rows;    
          try         
            if(result.rows.length != undefined && result.rows.length == 0) 
              resultSet = [];
             else if(enableJSONParse) 
              if(result.rows[0][0].type == oracledb.CLOB) 
                console.log("rows.type  is CLOB");
                resultSet = JSON.parse(result.rows[0][0]);
              
              resultSet = JSON.parse(result.rows);
                      

           catch(error) 
            callback(new InternalServerError("Error while parsing result of query: "+error.message));
            return;
          
         else  // In case query is INSERT/UPDATE/DELETE        
          console.log("Result.rowsAffected: " + result.rowsAffected);
          if(result.rowsAffected > 0) 
            resultSet = 'Executed Succesfully - Rows Affected: '+ result.rowsAffected;
           else 
            resultSet = 'No rows affected';
          
        
        doRelease(connection);
        callback(null, resultSet);                        
      );
  );

    // Note: connections should always be released when not needed
    function doRelease(connection) 
      connection.close(
        function(err) 
          if (err) 
              console.error(err.message);
              callback(new InternalServerError(err.message));
        return;
          
        );
  
;

`

【问题讨论】:

执行这个的代码在哪里? 我更新了问题,谢谢 您要更新的行是否已经有定义为NOT NULL所有列的数据? 对不起,我没有明白你的意思@MarkStewart,但如果你的意思是数据问题,不,这不是唯一性问题,甚至不是约束,因为所有列都接受空值,当然主键除外跨度> 您是否向 Oracle 传递了一大堆在您尝试执行的查询/语句中不存在的参数? 【参考方案1】:

问题是您要求 Oracle 为不存在的绑定参数设置值。

让我们考虑一下您的声明update assay_group set NAME=:groupName where ID=:id。 Oracle 将解析它,然后运行您的绑定参数。它将设置groupNameid 的值,然后它会得到名为externalName 的参数。但是,您的语句中没有绑定参数:externalName

Oracle 应该如何处理您赋予这个不存在的参数的值?您似乎期望 Oracle 忽略它。但是,忽略它不是一种选择:例如,如果有人输入错误的参数名称,我认为这应该立即产生错误,而不是等到所有其他参数都设置好然后抱怨其中一个参数丢失。

您必须将正在执行的查询或语句使用的参数传递给您的 executeQuery 函数,而不是其他参数。

【讨论】:

以上是关于NodeJS,Oracle DB参数的部分绑定给出:ORA-01036的主要内容,如果未能解决你的问题,请参考以下文章

为啥 BULK COLLECT 在 Oracle Package PROC 中给出错误的绑定变量编译错误?

通过 Oracledb Driver 使用 Nodejs 连接到远程 Oracle DB

DB笔试面试389在Oracle中,什么是绑定变量窥探?

在 Oracle 11g 中转换动态查询以使用绑定变量

从nodejs连接oracle

各位大侠,请教个oracle问题,执行一段代码出现错误,希望各位给出解决办法,谢谢谢!