ibmdb / node-ibm_db

IBM DB2 and IBM Informix bindings for node
MIT License
190 stars 151 forks source link

SQL Insertion Error SQL0104N to DB2 in Node Red #455

Closed cfkoh closed 6 years ago

cfkoh commented 6 years ago

I have a simple node red application that inserts sensor data message periodically into DB2. The SQL messages run successfully at the beginning, but it will return following error message after around 1 day.

"string[200] dashDB: Insert failed: Error: [IBM][CLI Driver][DB2/LINUXX8664] SQL0104N An unexpected token ")" was found following "into "SENSOR_DATA" (". Expected tokens may include: "". SQLSTATE=42601"

Below is the sql insert message. My question is if there is a syntax error in the message, why does it only return error after running for some time?

if (!msg.payload.sensor_0.data.lux) { msg.payload.sensor_0.data.lux = 0; }

if (!msg.payload.sensor_0.data.gyrox) { msg.payload.sensor_0.data.gyrox = 0; }

if (!msg.payload.sensor_0.data.gyroy) { msg.payload.sensor_0.data.gyroy = 0; }

if (!msg.payload.sensor_0.data.gyroz) { msg.payload.sensor_0.data.gyroz = 0; }

if (!msg.payload.sensor_0.data.rhum) { msg.payload.sensor_0.data.rhum = 0; } if (!msg.payload.vpan) { msg.payload.vpan = {id:0}; } if (!msg.payload.sensor_0.data.latency) { msg.payload.sensor_0.data.latency = 0; }

var ts = new Date(msg.timestamp); var a = ts.getMonth()+1; mon = (a < 10) ? ('0'+a) : a; a = ts.getDate(); dat = (a < 10) ? ('0'+a) : a; a = ts.getHours(); hr = (a < 10) ? ('0'+a) : a; a = ts.getMinutes(); min = (a < 10) ? ('0'+a) : a; a = ts.getSeconds(); sec = (a < 10) ? ('0'+a) : a; var dstr = ts.getFullYear()+'-'+mon+'-'+dat; var tstr = hr+':'+min+':'+sec;

var sqlMsg = { TIMESTAMP : msg.timestamp, DATE : dstr, TIME : tstr, GATEWAY_NAME : msg.payload.gateway_0.name, GATEWAY_GPS_LAT : msg.payload.gateway_0.gps[0], GATEWAY_GPS_LONG : msg.payload.gateway_0.gps[1], SENSOR_ID : msg.payload.sensor_0._id, TEMP : msg.payload.sensor_0.data.temp, PRES : msg.payload.sensor_0.data.press, HUM : msg.payload.sensor_0.data.rhum, LUX : msg.payload.sensor_0.data.lux, ACCELX : msg.payload.sensor_0.data.accelx, ACCELY : msg.payload.sensor_0.data.accely, ACCELZ : msg.payload.sensor_0.data.accelz, GYROX : msg.payload.sensor_0.data.gyrox, GYROY : msg.payload.sensor_0.data.gyroy, GYROZ : msg.payload.sensor_0.data.gyroz, BAT : msg.payload.sensor_0.data.bat, CC2650_ACTIVE : msg.payload.sensor_0.data.cc2650_active, CC2650_SLEEP : msg.payload.sensor_0.data.cc2650_sleep, RF_RX : msg.payload.sensor_0.data.rf_rx, RF_TX : msg.payload.sensor_0.data.rf_tx, GPSEN_ACTIVE : msg.payload.sensor_0.data.gpsen_active, GPSEN_SLEEP : msg.payload.sensor_0.data.gpsen_sleep, MSP432_ACTIVE : msg.payload.sensor_0.data.msp432_active, MSP432_SLEEP : msg.payload.sensor_0.data.msp432_sleep, EH : msg.payload.sensor_0.data.eh, EH1 : msg.payload.sensor_0.data.eh1, CHANNEL : msg.payload.sensor_0.data.channel, LATENCY : msg.payload.sensor_0.data.latency, VPAN: msg.payload.vpan.id };

msg = {payload : sqlMsg}; return msg;

.. I have two different Linux gateways that are doing https post to the node red application asynchronously, one with average data rate of 0.2 s per packet, and the other one with average data rate of 0.1s per packet. The node red application simply parses the received data and input the parsed data to the dashDB out module.

Kindly advice what could be the issue ?

bimalkjha commented 6 years ago

@cfkoh We can reproduce the error as below using Db2 command line processor:

C:\>db2 "insert into mytab1 values()"
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL0104N  An unexpected token ")" was found following "into mytab1 values(".
Expected tokens may include:  "<default_spec>".  SQLSTATE=42601

C:\>

You are getting error : An unexpected token ")" was found following "into "SENSOR_DATA" (".. It tells your SQL is: insert into "SENSOR_DATA" (). Seems query generator do not have any value to insert and hence framing query without any data. You should handle it at query generator level where if there is no data to insert then do not fire query for execution. Thanks.