abreits / node-red-contrib-oracledb

Node-RED oracle database nodes
8 stars 15 forks source link

ORA-01036 - Illegal variable name/number #1

Open mu45 opened 8 years ago

mu45 commented 8 years ago

We are trying to get node-red-contrib-oracledb running, yet to no (satisfying) avail. We've setup the Oracle schema 'testdb' on a remote machine. The device running node-red is equiped with the required Oracle libraries. We are actually able to insert a row into the table "DEMO" using SQLPLUS with the same credentials we configured the node with. Once we trigger the node to do an insert, we get the error "ORA-1036 - Illegal variable name/number". The query we fire is: "INSERT INTO DEMO (devid) VALUES ('3333');". Cases are correct, the column "devid" exists and is type varchar2(32). We have hacked the oracledb.js to output the query to the console log. It turns out that it is about to execute the query in the exact same way as posted above. Again, if I copy the query from the console log and paste it to SQLPLUS, it would just work fine. Could you give us any glue on what might be the cause for this behavior? Many thanks in advance!

abreits commented 8 years ago

I have no working oracle database at the moment to test against, so I cannot test it, but I suspect that the problem originates in the value binding.

Does the following code work in node.js? (example code from the node-oracledb library)

This should work (with the correct credentials):

oracledb.getConnection(
  {
    user          : "hr",
    password      : "welcome",
    connectString : "localhost/XE"
  },
  function(err, connection)
  {
    if (err) { console.error(err.message); return; }

    connection.execute(
      "INSERT INTO DEMO (devid) VALUES (:id)",
      ["3333"],  // bind value for :id
      function(err, result)
      {
        if (err) { console.error(err.message); return; }
        console.log(result.rows);
      });
  });

This should also should work (with the correct credentials):

oracledb.getConnection(
  {
    user          : "hr",
    password      : "welcome",
    connectString : "localhost/XE"
  },
  function(err, connection)
  {
    if (err) { console.error(err.message); return; }

    connection.execute(
      "INSERT INTO DEMO (devid) VALUES ('3333')",
      // ["3333"],  // bind value for :id <-- this line commented out
      function(err, result)
      {
        if (err) { console.error(err.message); return; }
        console.log(result.rows);
      });
  });

If my suspicion is correct this could create the error you are experiencing (with the correct credentials):

oracledb.getConnection(
  {
    user          : "hr",
    password      : "welcome",
    connectString : "localhost/XE"
  },
  function(err, connection)
  {
    if (err) { console.error(err.message); return; }

    connection.execute(
      "INSERT INTO DEMO (devid) VALUES ('3333')",
      [],  // bind value for :id <-- empty value array
      function(err, result)
      {
        if (err) { console.error(err.message); return; }
        console.log(result.rows);
      });
  });

If this is indeed the case, the workaround is to pass the value in the payload to the oracledb node (and for me to fix this bug).

I hope this helps, otherwise we will need to wait until next week, when our oracle DB admin is available for help.

abreits commented 8 years ago

I have found the source of the problem and fixed it (hopefully).

In the version 0.4.1 it should work.

mu45 commented 8 years ago

Hello, thank you, we will check it and give you an answer!

mu45 commented 8 years ago

We just tried and it wouldn't work, unfortunately.... Still the same error. I'm not quite sure if we've configured the node object in node-red correctly. Perhaps you might take a look over our configuration. The included sample query was taken out of the example insert1.js. Sorry to bother you with these beginner problems...

[{"id":"d49d0df8.aec208","type":"oracle-server","z":"3bd6cb2e.f63a74","host":"172.16.60.252","port":"1521","reconnect":true,"reconnecttimeout":"5000","db":"tobitestdb"},{"id":"ba7726e.e690ad8","type":"oracledb","z":"3bd6cb2e.f63a74","name":"Data2Oracled","usequery":true,"query":"\"INSERT INTO test VALUES (:id, :nm)\",\n [1, 'Chris']","usemappings":false,"mappings":"[\n\t\"location.of.first.array.index.field.in.msg.payload\",\n\t\"location.of.second.array.index.field\",\n\t\"last_array_indexfield.in[3]\"\n]","server":"d49d0df8.aec208","resultaction":"none","resultlimit":100,"x":471,"y":544,"wires":[["e6cda33f.de7af8"]]}]

abreits commented 8 years ago

Just tested your example, changed it to the following test (added a function node to insert the values):

[{"id":"16bf5677.c46cea","type":"oracle-server","z":"416d88f5.da9218","host":"172.16.60.252","port":"1521","reconnect":false,"reconnecttimeout":"5000","db":"tobitestdb"},{"id":"d6195622.0a1478","type":"oracledb","z":"416d88f5.da9218","name":"Data2Oracled","usequery":true,"query":"INSERT INTO test VALUES (:id, :nm)\n","usemappings":false,"mappings":"[\n\t\"location.of.first.array.index.field.in.msg.payload\",\n\t\"location.of.second.array.index.field\",\n\t\"last_array_indexfield.in[3]\"\n]","server":"16bf5677.c46cea","resultaction":"none","resultlimit":100,"x":687,"y":118,"wires":[[]]},{"id":"5fcab596.fe252c","type":"function","z":"416d88f5.da9218","name":"Insert values","func":"msg.payload =  [1, 'Chris'];\nreturn msg;","outputs":1,"noerr":0,"x":464,"y":125,"wires":[["d6195622.0a1478"]]},{"id":"2132bad0.5bdb1e","type":"inject","z":"416d88f5.da9218","name":"Insert test","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":249,"y":129,"wires":[["5fcab596.fe252c"]]}]

It complains about the table not existing (as expected because the table does not exist on my test machine), but should work otherwise.

I used the following node-red nodes to test a simple HR database query:

[{"id":"60b6c7ef.2b3dac","type":"oracle-server","z":"416d88f5.da9218","host":"localhost","port":"1521","reconnect":true,"reconnecttimeout":"5000","db":"orcl"},{"id":"671c1511.98e3ec","type":"oracledb","z":"416d88f5.da9218","name":"Test HR query","usequery":true,"query":"SELECT * FROM departments WHERE manager_id < 110","usemappings":false,"mappings":"[\n\t\"location.of.first.array.index.field.in.msg.payload\",\n\t\"location.of.second.array.index.field\",\n\t\"last_array_indexfield.in[3]\"\n]","server":"60b6c7ef.2b3dac","resultaction":"multi","resultlimit":100,"x":560,"y":706,"wires":[["d7a0b9ad.3140d"]]},{"id":"8e9a664.f716598","type":"inject","z":"416d88f5.da9218","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":185,"y":708,"wires":[["5ee75064.2841b4"]]},{"id":"5ee75064.2841b4","type":"function","z":"416d88f5.da9218","name":"","func":"msg.payload = [];\nreturn msg;","outputs":1,"noerr":0,"x":366,"y":707,"wires":[["671c1511.98e3ec"]]},{"id":"d7a0b9ad.3140d","type":"debug","z":"416d88f5.da9218","name":"","active":true,"console":"false","complete":"false","x":773,"y":714,"wires":[]}]

This should work if you can connect to the sample oracle HR database.

mu45 commented 8 years ago

Wow, this worked instantly! I guess we've missed the payload part and tried to just form a query as we would do on SQLPlus. Thank you very much for your quick and very detailed support!!!

phatao commented 7 years ago

below code may be helpful ---------post return sql result---------------------------------------------------------------------------------- `var oracledb = require("oracledb"); var dbConfig = require("../../oradb/dbconfig.js"); var winston = require("winston"); var err_code = Math.random().toString(32).substr(2);

module.exports = {

get : function (req,res){ res.send("this is GetAppDesc get page."); },

//POST方法 post : function (req, res) { "use strict"; if ("application/json" !== req.get('Content-Type')) { res.set('Content-Type', 'application/json').status(415).send(JSON.stringify({ status: 415, message: "Wrong content-type. Only application/json is supported", detailed_message: null })); return; } oracledb.getConnection( { user : dbConfig.user, password : dbConfig.password, connectString : dbConfig.connectString } , function (err, connection) { if (err) { // Error connecting to DB res.set('Content-Type', 'application/json').status(500).send(JSON.stringify({ status: 500, message: "Error connecting to DB", detailed_message: err.message })); winston.error(filename+" ,status(500)"+err_code+"=>",err.message); return; } connection.execute( " select "+ " sindv.id " + ",sindv.name " + ",sindv.description " + ",sindv.category " + ",sindv.type " + ",sindv.org_id " + ",sindv.organization_id " + ",sindv.set_of_books_id " + ",sindv.fnd_user_id " + ",sindv.mes_user_id " + ",sindv.language " + ",sindv.attribute1 " + ",sindv.attribute2 " + ",sindv.attribute3 " + ",sindv.attribute4 " + ",sindv.attribute5 " + ",sindv.type_code "+ ",sindv.type_code2 "+ ",sindv.type_code3 "+ ",sindv.type_code4 "+ ",sindv.type_code5 "+ ",sindv.type_code6 "+ ",sindv.type_code7 "+ ",sindv.type_code8 "+ ",sindv.type_code9 "+ ",sindv.type_code10 "+ " from apps.sfcapp_id_name_desc_v sindv "+ " where 1=1 " + " and (sindv.id =:id or lower(:id) in ('null','undefined') or :id is null) " + " and (sindv.name =:name or lower(:name) in ('null','undefined') or :name is null) " + " and (sindv.description =:description or lower(:description) in ('null','undefined') or :description is null) " + " and (sindv.category =:category or lower(:category) in ('null','undefined') or :category is null) " + " and (sindv.type =:type or lower(:type) in ('null','undefined') or :type is null) " + " and (sindv.org_id =:org_id or lower(:org_id) in ('null','undefined') or :org_id is null) " + " and (sindv.organization_id =:organization_id or lower(:organization_id) in ('null','undefined') or :organization_id is null) " + " and (sindv.set_of_books_id =:set_of_books_id or lower(:set_of_books_id) in ('null','undefined') or :set_of_books_id is null) " + " and (sindv.fnd_user_id =:fnd_user_id or lower(:fnd_user_id) in ('null','undefined') or :fnd_user_id is null) " + " and (sindv.mes_user_id =:mes_user_id or lower(:mes_user_id) in ('null','undefined') or :mes_user_id is null) " + " and (sindv.language =:language or lower(:language) in ('null','undefined') or :language is null) " + " and (sindv.attribute1 =:attribute1 or lower(:attribute1) in ('null','undefined') or :attribute1 is null) " + " and (sindv.attribute2 =:attribute2 or lower(:attribute2) in ('null','undefined') or :attribute2 is null) " + " and (sindv.attribute3 =:attribute3 or lower(:attribute3) in ('null','undefined') or :attribute2 is null) " + " and (sindv.attribute4 =:attribute4 or lower(:attribute4) in ('null','undefined') or :attribute4 is null) " + " and (sindv.attribute5 =:attribute5 or lower(:attribute5) in ('null','undefined') or :attribute5 is null) " + " and (sindv.type_code =:type_code or lower(:type_code) in ('null','undefined') or :type_code is null) " + " and (sindv.type_code2 =:type_code2 or lower(:type_code2) in ('null','undefined') or :type_code2 is null) " + " and (sindv.type_code3 =:type_code3 or lower(:type_code3) in ('null','undefined') or :type_code3 is null) " + " and (sindv.type_code4 =:type_code4 or lower(:type_code4) in ('null','undefined') or :type_code4 is null) " + " and (sindv.type_code5 =:type_code5 or lower(:type_code5) in ('null','undefined') or :type_code5 is null) " + " and (sindv.type_code6 =:type_code6 or lower(:type_code6) in ('null','undefined') or :type_code6 is null) " + " and (sindv.type_code7 =:type_code7 or lower(:type_code7) in ('null','undefined') or :type_code7 is null) " + " and (sindv.type_code8 =:type_code8 or lower(:type_code8) in ('null','undefined') or :type_code8 is null) " + " and (sindv.type_code9 =:type_code9 or lower(:type_code9) in ('null','undefined') or :type_code9 is null) " + " and (sindv.type_code10 =:type_code10 or lower(:type_code10) in ('null','undefined') or :type_code10 is null) " , { id : req.body.id ,name : req.body.name ,description : req.body.description ,category : req.body.category ,type : req.body.type ,org_id : req.body.org_id ,organization_id: req.body.organization_id ,set_of_books_id: req.body.set_of_books_id ,fnd_user_id : req.body.fnd_user_id ,mes_user_id : req.body.mes_user_id ,language : req.body.language ,attribute1 : req.body.attribute1 ,attribute2 : req.body.attribute2 ,attribute3 : req.body.attribute3 ,attribute4 : req.body.attribute4 ,attribute5 : req.body.attribute5 ,type_code : req.body.type_code ,type_code2 : req.body.type_code2 ,type_code3 : req.body.type_code3 ,type_code4 : req.body.type_code4 ,type_code5 : req.body.type_code5 ,type_code6 : req.body.type_code6 ,type_code7 : req.body.type_code7 ,type_code8 : req.body.type_code8 ,type_code9 : req.body.type_code9 ,type_code10 : req.body.type_code10 } , { outFormat: oracledb.OBJECT // Return the result as Object ,extendedMetaData: true }, function (err, result) { if (err) { // Error winston.error(filename+" ,status(400)"+err_code+"=>",err.message); res.set('Content-Type', 'application/json'); res.status(400).send(JSON.stringify({ status: 400, message: err.message.indexOf("ORA-00001") > -1 ? "User already exists" : "Input Error", detailed_message: err.message })); } else { if(result.rows.length==0) { res.status(200).send("[{\"data\":\"no_data_matches\"}]") } else { // Successfully created the resource res.status(200).send(result.rows); } } // Release the connection connection.release( function (err) { if (err) { console.error(err.message); winston.error(__filename+" ,"+err_code+"=>",err.message);

                 } else {
                   //console.log("POST /user_profiles : Connection released");
                   winston.info(__filename+" 讀取成功,"+err_code+"=>connection released");
                 }
               });
        });
});

} }

-------------------------post return procedure outbind-------------------------------------------------------- var oracledb = require("oracledb"); var dbConfig = require("../../oradb/dbconfig.js"); var winston = require("winston"); var err_code = Math.random().toString(32).substr(2);

module.exports = {

get : function (req,res){ res.send("this is QueryBarCode get page."); },

//POST方法 post : function (req, res) { "use strict"; if ("application/json" !== req.get('Content-Type')) { res.set('Content-Type', 'application/json').status(415).send(JSON.stringify({ status: 415, message: "Wrong content-type. Only application/json is supported", detailed_message: null })); return; } oracledb.getConnection( { user : dbConfig.user, password : dbConfig.password, connectString : dbConfig.connectString } , function (err, connection) { if (err) { // Error connecting to DB res.set('Content-Type', 'application/json').status(500).send(JSON.stringify({ status: 500, message: "Error connecting to DB", detailed_message: err.message })); winston.error(filename+" ,status(500)"+err_code+"=>",err.message); return; } connection.execute( "BEGIN apps.sfc_wip_api_query_pkg.main("+ "p_organization_id=>:orgID,"+ "p_barcode_number=>:barcodeNum,"+ "p_role_code=>:role,"+ "p_focus=>:focus,"+ "p_parameters=>:parameters,"+ "p_status_code=>:p_status_code,"+ "p_messages=>:p_message,"+ "p_user_id=>:userID"+ "); END;", { orgID : req.query.orgID, barcodeNum : req.query.barcodeNum, role : req.query.role, focus : req.query.focus, parameters : req.body.parameters , p_status_code : { type: oracledb.VARCHAR2, dir: oracledb.BIND_OUT }, p_message : { type: oracledb.VARCHAR2, dir: oracledb.BIND_OUT ,maxArraySize:50 }, userID : req.query.userID } , { autoCommit: true, outFormat: oracledb.OBJECT // Return the result as Object }, function (err, result) { if (err) { // Error winston.error(filename+" ,status(400)"+err_code+"=>",err.message); res.set('Content-Type', 'application/json'); res.status(400).send(JSON.stringify({ status: 400, message: err.message.indexOf("ORA-00001") > -1 ? "User already exists" : "Input Error", detailed_message: err.message })); } else { // Successfully created the resource res.status(200).send(result.outBinds); } // Release the connection connection.release( function (err) { if (err) { console.error(err.message); winston.error(__filename+" ,"+err_code+"=>",err.message);

                 } else {
                   //console.log("POST /user_profiles : Connection released");
                   winston.info(__filename+" 讀取成功,"+err_code+"=>connection released");
                 }
               });
        });
});

} }

-------------get return sql result------------------------------------------------------------------------------- /** *

var async = require("async"); var oracledb = require('oracledb'); var dbConfig = require('../../oradb/dbconfig.js'); var winston = require("winston"); var err_code = Math.random().toString(32).substr(2);

var sql = "select WDJ.WIP_ENTITY_ID,WDJ.WIP_ENTITY_NAME,WDJ.JOB_TYPE_MEANING JOB_TYPE," + "WDJ.CLASS_CODE,WDJ.STATUS_TYPE_DISP STATUS_TYPE," + "to_char(WDJ.SCHEDULED_START_DATE,'yyyy-mm-dd hh24:mi:ss') SCHEDULED_START_DATE,"+ "to_char(WDJ.DATE_RELEASED,'yyyy-mm-dd hh24:mi:ss') DATE_RELEASED,"+ "msib.primary_uom_code,WDJ.START_QUANTITY," + "WDJ.QUANTITY_REMAINING,WDJ.QUANTITY_COMPLETED,WDJ.LOT_NUMBER," + "WDJ.COMPLETION_SUBINVENTORY,WDJ.DEMAND_CLASS " + "from apps.WIP_DISCRETE_JOBS_V WDJ,apps.mtl_system_items_b msib " + "where wdj.organization_id=msib.organization_id " + "and wdj.primary_item_id=msib.inventory_item_id " + "and WDJ.ORGANIZATION_ID="+req.query.orgid+" " + "and (WDJ.WIP_ENTITY_NAME='"+req.query.jobnum+"' or lower('"+req.query.jobnum+"' ) in ('null','undefined')) "+ "and (WDJ.WIP_ENTITY_ID='"+req.query.jobid+"' or lower('"+req.query.jobid+"' ) in ('null','undefined')) " ; /*

var doconnect = function(cb) { oracledb.getConnection(dbConfig, cb); };

var dorelease = function(conn) { conn.close(function (err) { if (err) console.error(err.message); }); };

var dojsonquery = function (conn, cb) { winston.info(__filename+" ,"+err_code+"=>"+sql);

conn.execute( sql, [], { outFormat: oracledb.OBJECT, extendedMetaData: true }, function(err, result) { if (err){ winston.error(filename+" "+err_code+"=>",err); console.error(err); console.log(sql); var e = {"Message":+""+err}; callback(e); } else{ if (result.rows.length === 0) { winston.info(__filename+" 抓不到資料,"+err_code+"=>",err); callback(result.rows); } else { winston.info(filename+" 讀取成功,"+err_code+"=>"+result); callback(result.rows); } } }); };

async.waterfall( [ doconnect, dojsonquery ], function (err, conn) { if (err) { winston.error(__filename+" "+err_code+"In waterfall error cb: ==>",err); console.error(err.message); var e = {"In waterfall error cb: ==>":err}; callback(e);

}
if (conn)
  dorelease(conn);

}); }

exports.run = run; `