Related
I have recently inherited a process that requires running queries in MS Access database. Yesterday I stumbled upon the following weird issue, which I can not logically explain:
The query does not run in the latest version of the database file (August 2021 data)
Error message: "undefined VAL() function". When I remove VAL(), a new error message appears: "undefined MID() function"; the messages do not make any sense, as both functions are used in MS SQL.
The same query ran fine in the earlier (May 2021) version of the database, which I downloaded from the corporate server (backup copy, available through "previous versions")
when I copy the query from May database to Aug database, I receive error messages as in "1" (above).
When I copy data from Aug file into May file, the query runs fine. This makes me think that the problem is not a data issue.
I am not sure if the person who produced the reporting before me has done something with August file, or whether this is a weird computer glitch...
I know how to fix the problem (i.e. by copying data from August database to May database), but I am at a loss as to the cause of the error. Any assistance will be highly appreciated!
SQL Query Code (converts USD to CAD):
UPDATE T1_DEF_EXPENSETYPE_COST AS F1, SM_FX_MAVG AS F2 SET F1.CDE = F1.COA * IIF( CURRENCY_TYPE = 'CAD',1,
IIF(MID(F1.PERIOD,10,2) = '01',F2.[M12],0) +
IIF(MID(F1.PERIOD,10,2) = '02',F2.[M01],0) +
IIF(MID(F1.PERIOD,10,2) = '03',F2.[M02],0) +
IIF(MID(F1.PERIOD,10,2) = '04',F2.[M03],0) +
IIF(MID(F1.PERIOD,10,2) = '05',F2.[M04],0) +
IIF(MID(F1.PERIOD,10,2) = '06',F2.[M05],0) +
IIF(MID(F1.PERIOD,10,2) = '07',F2.[M06],0) +
IIF(MID(F1.PERIOD,10,2) = '08',F2.[M07],0) +
IIF(MID(F1.PERIOD,10,2) = '09',F2.[M08],0) +
IIF(MID(F1.PERIOD,10,2) = '10',F2.[M09],0) +
IIF(MID(F1.PERIOD,10,2) = '11',F2.[M10],0) +
IIF(MID(F1.PERIOD,10,2) = '12',F2.[M11],0)), F1.FX_PERIOD = MID(F2.PERIOD,4,4) &
IIF(MID(F1.PERIOD,10,2) = '01','-M12','') &
IIF(MID(F1.PERIOD,10,2) = '02','-M01','') &
IIF(MID(F1.PERIOD,10,2) = '03','-M02','') &
IIF(MID(F1.PERIOD,10,2) = '04','-M03','') &
IIF(MID(F1.PERIOD,10,2) = '05','-M04','') &
IIF(MID(F1.PERIOD,10,2) = '06','-M05','') &
IIF(MID(F1.PERIOD,10,2) = '07','-M06','') &
IIF(MID(F1.PERIOD,10,2) = '08','-M07','') &
IIF(MID(F1.PERIOD,10,2) = '09','-M08','') &
IIF(MID(F1.PERIOD,10,2) = '10','-M09','') &
IIF(MID(F1.PERIOD,10,2) = '11','-M10','') &
IIF(MID(F1.PERIOD,10,2) = '12','-M11',''), F1.FX_Rate = IIF( CURRENCY_TYPE = 'CAD',1,
IIF(MID(F1.PERIOD,10,2) = '01',F2.[M12],0) +
IIF(MID(F1.PERIOD,10,2) = '02',F2.[M01],0) +
IIF(MID(F1.PERIOD,10,2) = '03',F2.[M02],0) +
IIF(MID(F1.PERIOD,10,2) = '04',F2.[M03],0) +
IIF(MID(F1.PERIOD,10,2) = '05',F2.[M04],0) +
IIF(MID(F1.PERIOD,10,2) = '06',F2.[M05],0) +
IIF(MID(F1.PERIOD,10,2) = '07',F2.[M06],0) +
IIF(MID(F1.PERIOD,10,2) = '08',F2.[M07],0) +
IIF(MID(F1.PERIOD,10,2) = '09',F2.[M08],0) +
IIF(MID(F1.PERIOD,10,2) = '10',F2.[M09],0) +
IIF(MID(F1.PERIOD,10,2) = '11',F2.[M10],0) +
IIF(MID(F1.PERIOD,10,2) = '12',F2.[M11],0))
WHERE F1.COA IS NOT NULL AND
VAL(MID(F1.PERIOD,4,4)) = VAL(MID(F2.PERIOD,4,4)) + VAL(IIF(MID(F1.PERIOD,10,2) = '01',1,0)) AND
F2.BASE_RATE = 'CAD' AND F2.CURRENCY_CODE = 'USD';
The function below calls and sends an email for ALL rows that are marked "Closed"; but I want it to only email the one that gets marked "Closed"; not older, previously closed rows and I don't know how to correct this, please help.
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 3;
var numRows = 5000;
var dataRange = sheet.getRange(startRow, 1, numRows, 5000);
var data = dataRange.getValues();
var FinalMessage;
for (var i in data) {
var row = data[i];
if (row.includes("Closed")){
// Logger.log("CLOSED" + row);
var emailAddress = ""
var TSRNumber = row[19];
var IssueType = row[4];
var Customer = row[5];
var TankCode = row[13];
var City = row[9];
var State = row[10];
var Region = row[0];
var Terminal = row[1];
switch (Terminal) {
case "Riga MI":
emailAddress = "xxxxxx#xxxx.com";
break;
case "Other":
default:
emailAddress = "xxxx#xxxx.com";
break;
}
var subject = "CLOSED - TSR #" + TSRNumber + " for " + Customer + " in " + City + " " + State
+ " ( " + Region + " )";
var message = "TSR # " + TSRNumber + " for " + Customer + " in " + City + " " + State + " ( "
+ Region + " ) " + "is now Closed" +'\n' +'\n' + "Link to TSR Database: " +
"https://xxxxx.com"
MailApp.sendEmail(emailAddress, "NO-REPLY#xxxxx.com", subject, message);
}
}
}
You would need an installable trigger for this scenario:
function createTrigger() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ScriptApp.newTrigger('sendEmail').forSpreadsheet(ss).onEdit().create();
}
This function, when executed manually, will create a trigger for the spreadsheet that will fire when a cell is edited.
Then the sendEmail function itself would then read the edited cell, validate, and fill out the fields as usual:
function sendEmail(e) {
var sheet = SpreadsheetApp.getActiveSheet();
if ((e.range.getRow() >= 3) && (e.range.getValue() === "Closed")) {
var row = sheet.getRange(e.range.getRow(),1,1,20).getValues();
var emailAddress = ""
var TSRNumber = row[19];
var IssueType = row[4];
var Customer = row[5];
var TankCode = row[13];
var City = row[9];
var State = row[10];
var Region = row[0];
var Terminal = row[1];
switch (Terminal) {
case "Riga MI":
emailAddress = "xxxxxx#xxxx.com";
break;
case "Other":
default:
emailAddress = "xxxx#xxxx.com";
break;
}
var subject = "CLOSED - TSR #" + TSRNumber + " for " + Customer + " in " + City + " " + State
+ " ( " + Region + " )";
var message = "TSR # " + TSRNumber + " for " + Customer + " in " + City + " " + State + " ( "
+ Region + " ) " + "is now Closed" +'\n' +'\n' + "Link to TSR Database: " +
"https://xxxxx.com"
MailApp.sendEmail(emailAddress, "NO-REPLY#xxxxx.com", subject, message);
}
}
References:
Installable Triggers
Values are not inserting in table login even though the query's response is showing "inserted" but table is not updated with the new row.
var mysql = require('mysql')
router.get('/save',function(req,res){
var uname = req.query.username;
var em = req.query.email;
var pass = req.query.pass;
var gender = req.query.gender;
var dob = req.query.date;
var con = mysql.createConnection({
host:"localhost",
user:"root",
password:"abcd1234",
database:"nodedb"
});
con.query('insert into login(username, email, password, gender, DOB)
VALUES("' + uname + '","' + em + '","' + pass + '","' + gender + '","' + dob + '")',function(err,rows,fields){
console.log(rows);
res.send("inserted");
});
con.end();
});
module.exports = router;
result shows
"inserted"
although the values are not inserted in my table.
var mysql = require('mysql')
router.get('/save',function(req,res){
var uname = req.query.username;
var em = req.query.email;
var pass = req.query.pass;
var gender = req.query.gender;
var dob = req.query.date;
var con = mysql.createConnection({
host:"localhost",
user:"root",
password:"abcd1234",
database:"nodedb"
});
var sql = "INSERT INTO login (username, email, password, gender, DOB) VALUES ('" + uname + "'" + ',' + "'" + em + "'" + ',' + "'" + pass + "'" + ',' + "'" + gender + "'" + ',' + "'" + dob + "')";
con.query(sql, function (err, result) {
if (err) throw err;
console.log("1 record inserted");
console.log(result);
});
});
module.exports = router;
Try the code above....
Note sql keywords are written in capital letters.
By the way, using raw sql in nodejs is tiresome so its better that you try using an ORM some time
I have tried doing this several ways, and maybe node.js is the wrong language to use for this purpose, but I thought it could be quickly done with it. I am taking a contacts table with names and addresses, and converting it to two tables with a one-to-many relationship, so that one contact can have multiple addresses. The desired data structure is like this:
Contact Table
contactId
firstName
lastName
phone
email
etc...
Address Table
addressId
contactId
street
city
state
etc...
Currently all fields are in the same table.
The result I am getting is that the data in the second query never changes. So if I write the contact query first, then it works as expected, but the addresses all end up as duplicates of one contact's address. If I insert the address record first, then I get duplicate records of one contact. I tried nesting the queries first, but I split them out when I got this behavior. My thinking was that I could write the queries . I need to write the contact and get the ID back, then write the address with the contactID. OR I need to write the address and get THAT ID back, and then write the contact, get that ID, and then do an update query to put the contactId into the address record. This last method is the attempt shown in the code below.
Here is my code currently:
var sql = "SELECT * FROM pfPeople";
connection.query(sql, function(err, result, fields) {
if (err) throw err;
for (var i = 0; i < result.length; i++) {
var names = result[i].fullName.replace(/"/g, "'").split(" ");
var sql2 = "INSERT INTO contact (firstName, lastName, title, phone1, phone2, fax, email1, notes, org) VALUES (" +
"\"" + names[0] + "\", \"" + names[1] + "\", \"" + result[i].title.replace(/"/g, "'") + " \", \"" + result[i].phone1 + "\", \"" +
result[i].phone2 + "\", " + "\"" + result[i].phone3 + "\", \"" + result[i].email + "\", \"" + result[i].notes.replace(/"/g, "'") + "\", \"" +
result[i].org.replace(/"/g, "'") + "\")";
var street = result[i].street;
var city = result[i].city;
var state = result[i].state;
var zip = result[i].zip;
var country = result[i].country;
var sql3 = "INSERT INTO address (address1, city, state, zip, country) VALUES (" +
"\"" + street + "\", \" " + city + "\", \"" + state + "\", \"" + zip + "\", \"" + country + "\")";
var contactId;
var addressId;
connection.query(sql2, function(err, cResult) {
if (err) throw err;
var contactId = cResult.insertId;
console.log("Inserted ID: " + contactId);
});
connection.query(sql3, function(err, aResult) {
if (err) throw err;
var addressId = aResult.insertId;
});
var sql4 = "UPDATE address set contactId = " + contactId + " WHERE (addressId = " + addressId + ")";
connection.query(sql4, function(err, uRes) {
console.log("Address updated " + addressId + " " + contactId);
});
if (i > 3) break;
}
});
well i add some promises to make it easier. the problem was you didnt wait for the responses to finish. try this code
var sql = "SELECT * FROM pfPeople";
connection.query(sql, function(err, result, fields) {
if (err) throw err;
for (var i = 0; i < result.length; i++) {
var names = result[i].fullName.replace(/"/g, "'").split(" ");
var sql2 = "INSERT INTO contact (firstName, lastName, title, phone1, phone2, fax, email1, notes, org) VALUES (" +
"\"" + names[0] + "\", \"" + names[1] + "\", \"" + result[i].title.replace(/"/g, "'") + " \", \"" + result[i].phone1 + "\", \"" +
result[i].phone2 + "\", " + "\"" + result[i].phone3 + "\", \"" + result[i].email + "\", \"" + result[i].notes.replace(/"/g, "'") + "\", \"" +
result[i].org.replace(/"/g, "'") + "\")";
var street = result[i].street;
var city = result[i].city;
var state = result[i].state;
var zip = result[i].zip;
var country = result[i].country;
var sql3 = "INSERT INTO address (address1, city, state, zip, country) VALUES (" +
"\"" + street + "\", \" " + city + "\", \"" + state + "\", \"" + zip + "\", \"" + country + "\")";
const contacPromise = new Promise((resolve,reject) =>{
connection.query(sql2, function(err, cResult) {
if (err) return reject( err);
resolve( cResult.insertId);
});
})
const addressPromise = new Promise((resolve,reject) =>{
connection.query(sql3, function(err, aResult) {
if (err) return reject( err);
resolve(aResult.insertId);
});
})
Pomise.all([contacPromise,addressPromise])
.then(([contactId,addressId]) =>{
var sql4 = "UPDATE address set contactId = " + contactId + " WHERE (addressId = " + addressId + ")";
connection.query(sql4, function(err, uRes) {
console.log("Address updated " + addressId + " " + contactId);
});
})
.catch(err => throw err)
if (i > 3) break;
}
});
I am writing node js application which fetches 100 000 records from SQL server database and insert those into mysql database. I have done with code but my application not give me expected performance.
My selection of 100k records takes 9-10 sec and bulk insertion process takes 3-4 sec. I want node to speed up selection process (need 3-4 sec to select record from sql server). I tried using 2 ways but still unable to achieve expected time.
/*First Way*/
var sql = require('mssql');
var mysql = require("mysql");
var sizeof = require('sizeof');
var moment = require('moment');
var config = {
user: '**',
password: '*****',
server: '******',
database: '*******'
}
var connection1 = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'root',
database : 'test'
});
connection1.connect();
sql.connect(config, function(err) {
if(err)
console.log(err);
console.log('Connecting to Sql Server');
console.time('Overall Time-Taken');
var request = new sql.Request();
console.time('Time-Taken to fetch');
request.query('select TOP 100000 * from ShipmentAuditLog WITH (NOLOCK)', function(err, recordset) {
if(err)
console.log(err);
else{
//console.log(sizeof(recordset));
console.timeEnd('Time-Taken to fetch');
syncing(recordset);
}
});
});
function mapping(row) {
var formatedString = '';
var CreatedDate = new moment(row.CreatedDate).format('YYYY-MM-DD HH:mm:ss');
row.Process = row.Process.replace(/'/g,"\\'");
if(row.Comment != null){
formatedString = row.Comment;
formatedString = formatedString.replace(/'/g,"\\'");
row.Comment = formatedString;
}
return "('" + row.ShippingID + "','" + row.BagNo + "','" + row.ProcessLocation + "','" + row.Process + "','" + row.Comment + "','" + CreatedDate + "','" + row.CreatedBy + "','" + row.LastModifiedDate + "','" + row.LastModifiedBy + "','" + row.DestinationLocation + "','" + row.VenderLostShipmentsDebitId + "', NOW())";
//return "('" + row.ShippingID + "','" + row.BagNo + "','" + row.ProcessLocation + "','" + row.Process + "','" + row.Comment + "','" + CreatedDate + "','" + row.CreatedBy + "','" + row.LastModifiedDate + "','" + row.LastModifiedBy + "','" + row.DestinationLocation + "','" + row.VenderLostShipmentsDebitId + "')";
}
var syncing = function(recordset){
//var columns = [];
var values = [];
/*for(col in recordset[0]){
columns.push(col);
}*/
/*for(var i=0,len = recordset.length;i<len;i+=1){
values.push(mapping(recordset[i]));
}*/
recordset.forEach(function(record){
values.push(mapping(record));
})
//console.log(values);
console.time('Time-Taken to Insert');
var QRY = connection1.query('INSERT INTO shipmentauditlog VALUES'+ values.join(','), function(err, result) {
if (err) {
console.log(err);
}
else {
console.timeEnd('Time-Taken to Insert');
console.timeEnd('Overall Time-Taken');
}
});
//console.log(QRY.sql);
}
/*Second Way*/
var sql = require('mssql');
var mysql = require("mysql");
var moment = require('moment');
var config = {
user: '**',
password: '***',
server: '****',
database: '****',
stream: true
}
var connection1 = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'root',
database : 'test'
});
connection1.connect();
var values = [];
function mapResult(row){
var formatedString = '';
var CreatedDate = new moment(row.CreatedDate).format('YYYY-MM-DD HH:mm:ss');
row.Process = row.Process.replace(/'/g,"\\'");
if(row.Comment != null){
formatedString = row.Comment;
formatedString = formatedString.replace(/'/g,"\\'");
row.Comment = formatedString;
}
return "('" + row.ShippingID + "','" + row.BagNo + "','" + row.ProcessLocation + "','" + row.Process + "','" + row.Comment + "','" + CreatedDate + "','" + row.CreatedBy + "','" + row.LastModifiedDate + "','" + row.LastModifiedBy + "','" + row.DestinationLocation + "','" + row.VenderLostShipmentsDebitId + "', NOW())";
}
var connection = new sql.Connection(config, function(err) {
if(err)
console.log(err);
console.log('Connecting to Sql Server');
console.time('Overall Time-Taken');
var request = new sql.Request(connection);
//request.stream = true;
request.query('select TOP 100000 * FROM ShipmentAuditLog WITH (NOLOCK)'); // or request.execute(procedure);
request.on('recordset',function(col){
console.time('Time-Taken to fetch');
});
// Emitted for each row
request.on('row', function(row) {
//Build array with resultset for bulk insert
values.push(mapResult(row));
});
request.on('error', function(err) {
console.log(err);
});
// Emitted for the last one
request.on('done', function(returnValue) {
console.timeEnd('Time-Taken to fetch');
// Function which perform bulk insert into mysql
syncing(values);
connection.close();
});
});
var syncing = function(values){
/*var startTime = new Date();
console.log("Start Time :"+ startTime);*/
console.time('Time-Taken to Insert');
var qry = connection1.query('INSERT INTO shipmentauditlog VALUES'+values.join(','),function(err,res){
if(err)
console.log(err);
else{
/*var endTime = new Date();
console.log('End Time:'+ endTime);*/
console.timeEnd('Time-Taken to Insert');
console.timeEnd('Overall Time-Taken');
}
});
}