NodeJS,Oracle DB 参数的部分绑定给出:ORA-01036
NodeJS ,Partial binding of Oracle DB parameters gives : ORA-01036
我正在处理一项 insert/update 的任务 table。
当我在 insert/update 语句中使用 table 的完整列时,它对我有用
但是每当我只更新所需的列而忽略其余未触及的列时,我都会遇到 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":"Error while executing query - ORA-01036: illegal variable name/number\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;
}
});
}
};
`
问题是您要求 Oracle 为不存在的绑定参数设置值。
让我们考虑一下您的陈述 update assay_group set NAME=:groupName where ID=:id
。 Oracle 将对此进行解析,然后 运行 通过您的绑定参数。它会很好地设置 groupName
和 id
的值,然后它会到达名为 externalName
的参数。但是,您的语句中没有绑定参数 :externalName
。
Oracle 应该如何处理您赋予这个不存在的参数的值?您似乎希望 Oracle 忽略它。但是,忽略它不是一种选择:例如,如果有人输入错误的参数名称,我认为这应该立即产生错误,而不是等到所有其他参数都已设置,然后抱怨其中一个丢失。
您必须将正在执行的查询或语句使用的参数传递给您的 executeQuery
函数,而不是其他参数。
我正在处理一项 insert/update 的任务 table。
当我在 insert/update 语句中使用 table 的完整列时,它对我有用 但是每当我只更新所需的列而忽略其余未触及的列时,我都会遇到 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":"Error while executing query - ORA-01036: illegal variable name/number\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;
}
});
}
};
`
问题是您要求 Oracle 为不存在的绑定参数设置值。
让我们考虑一下您的陈述 update assay_group set NAME=:groupName where ID=:id
。 Oracle 将对此进行解析,然后 运行 通过您的绑定参数。它会很好地设置 groupName
和 id
的值,然后它会到达名为 externalName
的参数。但是,您的语句中没有绑定参数 :externalName
。
Oracle 应该如何处理您赋予这个不存在的参数的值?您似乎希望 Oracle 忽略它。但是,忽略它不是一种选择:例如,如果有人输入错误的参数名称,我认为这应该立即产生错误,而不是等到所有其他参数都已设置,然后抱怨其中一个丢失。
您必须将正在执行的查询或语句使用的参数传递给您的 executeQuery
函数,而不是其他参数。