How do I remove backticks in formatted mysql query? - mysql

Okay so I've extracted some values in excel using the npm package 'xlsx' and I want to run a MySql query with the formatted result.
Excel extraction
let wb= xlsx.readFile(filePath); //GET WORKBOOK
let ws= wb.Sheets[wb.SheetNames[0]]; //SELECT THE FIRST SHEET IN THE ARRAY
let data= xlsx.utils.sheet_to_json(ws); //CONVERT DATA TO JSON OBJECT
let s =''; //CREATE VARIABLE TO HOLD FORMATTED STRING
for(let i=0; i<data.length; i++){
s+= "'" + data[i].id +"',"; //FORMAT OBJECT TO STRING
}
let fullString= s.substr(0, s.length-1); //STORE FORMATED STRING IN VARIABLE REMOVING FINAL COMMA (,)
Formated string is like so:
'2019-0027178','2019-0027179','2019-0027180','2019-0027181','2019-0027182','2019-0027183'
MySql query is like so:
SELECT name, email, phone FROM persons WHERE id IN (?),
[fullString]
What's expected:
A json object containing the requested information like so:
[{name: "John", email: "john.doe#email.com", phone: "123456789"}, ... ]
Actual result:
An empty array like so:
[]
Investigation and Thoughts
I found out backticks were being added to the query string like so:
... WHERE id IN (`'2019-0027178','2019-0027179','2019-0027180','2019-0027181','2019-0027182','2019-0027183'`)
Actual actual main question:
Is there something I'm doing wrong or is there a proper way to do this?
EDIT!
So for a single question mark ie. ... WHERE id in (?), I get the empty object as stated above. But for two question marks ie. ... WHERE id IN (??), I get this error:
{
"code": "ER_BAD_FIELD_ERROR",
"errno": 1054,
"sqlMessage": "Unknown column ''2019-0027178','2019-0027179','2019-0027180','2019-0027181','2019-0027182','2019-0027183' in 'where clause'",
"sqlState": "42S22",
"index": 0,
"sql": "SELECT name, email, phone FROM persons WHERE id IN (`'2019-0027178','2019-0027179','2019-0027180','2019-0027181','2019-0027182','2019-0027183'`)"
}

Lets say you had a table called personfilter with the columns key and personid.
You then generate a unique key. For example 27. Then the following would do what you want:
INSERT INTO personfilter(key,personid)
values
(27, '2019-0027178'),
(27, '2019-0027179'),
(27, '2019-0027180'),
(27, '2019-0027181'),
(27, '2019-0027182'),
(27, '2019-0027183')
Then you could do the following select
SELECT name, email, phone
FROM persons
JOIN personfilter on personfilter.key = 27 and personfilter.personid = persons.id

Okay so I figured I could just 'prepare' the query before executing it.
~SOLUTION~
Instead of doing this let fullString= s.substr(0, s.length-1); before passing fullString as a parameter to the query string, I just did this:
let fullString= `SELECT name, email, phone FROM persons WHERE id IN (${s.substr(0, s.length-1)})`;
Then passed fullString in place of where the actual query was.
Thanks.

Related

Mysql for NodeJS not expanding array in queries

I'm using NodeJS and the mysql package from npm. I'm having trouble selecting specific rows from the database by ID. I'm using a simple WHERE id IN (...) query, and passing in the ids as an array of numbers.
According to the documentation,
Arrays are turned into list, e.g. ['a', 'b'] turns into 'a', 'b'
So I've written this code to debug the SQL it generates:
console.log(ids);
console.log(this.connection.format(
"SELECT `invitations`.* FROM `invitations` WHERE `invitations`.`id` IN (?)",
ids
));
I expect to see a list of ids first, then the SQL statement where those ids are in the IN section of the query.
However, only the first id is present in the query:
console.log tests/fakers/InvitationFaker.ts:70
[ 207, 208 ]
console.log tests/fakers/InvitationFaker.ts:71
SELECT `invitations`.* FROM `invitations` WHERE `invitations`.`id` IN (207)
Why doesn't the query look like this:
... WHERE `invitations`.`id` IN (207, 208)
?
try to convert the ids to string with "," between the ids
this.connection.format(
"SELECT `invitations`.* FROM `invitations` WHERE `invitations`.`id` IN (?)",
ids.join(",")
));
I'm an idiot :) I forgot that the second argument can be either a single value or an array, but when it's an array, the first value fills the first ? and so on. To expand an array, I need to do this:
" ... WHERE `id` IN ?", [ids]
(note the double array, since ids is already an array). For example:
" ... WHERE `id` IN ?", [[1, 2, 3, 4]]

MariaDB COLUMN_JSON query returns binary

I've been trying to use dynamic columns with an instance of MariaDB v10.1.12.
First, I send the following query:
INSERT INTO savedDisplays (user, name, body, dataSource, params) VALUES ('Marty', 'Hey', 'Hoy', 'temp', COLUMN_CREATE('type', 'tab', 'col0', 'champions', 'col1', 'averageResults'));
Where params' type was defined as a blob, just like the documentation suggests.
The query is accepted, the table updated. If I COLUMN_CHECK the results, it tells me it's fine.
But when I try to select:
"SELECT COLUMN_JSON(params) AS params FROM savedDisplays;
I get a {type: "Buffer", data: Array} containing binary returned to me, instead of the {"type":"tab", "col0":"champions", "col1":"averageResults"} I expect.
EDIT: I can use COLUMN_GET just fine, but I need every column inside the params field, and I need to check the type property first to know what kind of and how many columns there are in the JSON / params field. I could probably make it work still, but that would require multiple queries, as opposed to only one.
Any ideas?
Try:
SELECT CONVERT(COLUMN_JSON(params) USING utf8) AS params FROM savedDisplays
In MariaDB 10 this works at every table:
SELECT CONVERT(COLUMN_JSON(COLUMN_CREATE('t', text, 'v', value)) USING utf8)
as json FROM test WHERE 1 AND value LIKE '%12345%' LIMIT 10;
output in node.js
[ TextRow { json: '{"t":"test text","v":"0.5339044212345805"}' } ]

Meteor: how do I return data from fields in a specific object?

This should be a fairly simple one.
myobject has various properties, _id, name, createdBy, date etc
In my find query I want to only return specific fields from within myObject. So for example, what would I need to do to modify the find query below so that only name was returned?
myCollection.find({createdBy: someId}, {fields: {myObject: 1}}).fetch();
Currently this will return everything in myObject which it should do, I just want one field within myObject returned.
Here is a way to do it within the query:
myCollection.find({createdBy: someId}, {fields: {'myObject.name':
1}}).fetch();
Note the quotes around
'myObject.name'
Lets assume we are talking about posts, and a post document looks like this:
{
_id: 'abc123',
title: 'All about meteor',
author: {
firstName: 'David',
lastName: 'Weldon'
}
}
You can then extract all of the last names from all of the authors with this:
var lastNames = Posts.find().map(function(post) {
return post.author.lastName;
});
Modify the selector and options as needed for your collection. Using fields in this case may be a small optimization if you are running this on the server and fetching the data directly from the DB.

Insert geometry values in mysql using node.js

I am using https://github.com/felixge/node-mysql module with node.js.
Mysql table has a field of type POINT. The module requires to send array of arrays to insert bulk records. But It doesn't seem to have option to specify data type.
So naturally, the following gets enclosed in quotes
var loc = "GeomFromText('POINT(" + lat + "," + lon + ")')";
Has anybody tried this? How can I convince the query builder to treat this as an sql function?
Or do I have to make my own query builder?
There is a pull request from kevinhikaruevans that does it. You can do something like that to convert objects to points:
if (typeof val === 'object') {
if(val.hasOwnProperty('lat') && val.hasOwnProperty('long')) {
return 'POINT(' + [val.lat, val.long].map(parseFloat).join(',') + ')';
}
}
Supposing you have a table mytable with only the field point of type POINT, you would insert them like this:
var points = [
[{ lat: 1, long: 4}],
[{ lat: 23, long: -8.345}]
];
var query = connection.query('INSERT INTO mytable(point) VALUES ?', [points], your_callback_func);
console.log("Query: " + query.sql);
This will generate a query similar to:
INSERT INTO mytable(point)
VALUES (POINT(1,4)), (POINT(23,-8.345))
This would convert any object with both lat and long fields to a MySQL point. If this is not an intended behavior, you could create a Point class and use it instead of plain objects, and in lib/protocol/SqlString.js check if the value is an instance of Point.
Try constructing a query to handle POINT() and batch where site is an object with properties and values shown below. This approach works for me.
pool.query('INSERT INTO table SET geometryField = POINT(?,?), ?',[coords.lat,coords.lng,site], function(err, response) {
{ sitename: 'A Site',
customer: 'A Customer',
country: 'AL',
timezone: 'America/Los_Angeles',
address1: '123 My Street',
city: 'MyCity',
state: 'WA',
postalcode: '98110'}

sql for a fuzzy search query

I have an sql query for a mysql database that includes the following
where("UPPER(CONCAT(firstName, ' ', lastName)) LIKE ?", params[:query])
Since sqlite3 doesn't have the concat function, but instead uses pipes ||, I tried to write the above as
where("UPPER(firstName || ' ' || lastName) LIKE ?", params[:query])
but the query isn't returning any results. Am I not using the || correctly?
note, the lowercase where is the Rails query helper.
Update
It turns out that the concat operator wasn't the problem, so I changed the title to this question. I'm trying to do a fuzzy search on a name, namely to return all records that contain the search term in the person's name. For example, if you search "a", "tanja" would be a postive match the server is running this query with my sql
This is the sql that is being run (if an "a" was entered in the search box)
SELECT id, firstname, lastname, title FROM "employees" WHERE (upper(firstName ||' '||lastName) LIKE 'a')
The ajax request (as shown by the console) is this
findByName: a employee.js:20
XHR finished loading: "http://localhost:3000/employees/search/a". jquery.js:8215
[] ##empty array returned
If I run the query in the Rails console, it also returns empty so maybe the problem is with my sql
>> Employee.select("id, firstname, lastname, title").where("upper(firstName ||' '||lastName) LIKE ?", "a")
Employee Load (0.2ms) SELECT id, firstname, lastname, title FROM "employees" WHERE (upper(firstName ||' '||lastName) LIKE 'a')
=> []
However, there are records in the db with names containing the letter "a." This is the database record, for example. Can anyone explain why a query like the above (assuming the person's name contained the searched for letter) wouldn't work on a record like this.
[#<Employee id: 1, firstname: "Steven", lastname: "Wells", managerid: 4, title: "Software Architech", department: "Engineering", officephone: "604-999-8989", cellphone: "345-678-0987", email: "sweels#email.com", city: "Vancouer", picture: "assets/steven_wells.jpg", twitterid: "#fartbreath", blogurl: "http://blahblah.com", created_at: "2013-01-16 01:24:38", updated_at: "2013-01-16 01:24:38">,
Can anyone explain what the problem might be?
I'm not sure, but do you need some wildcards with the "a"? e.g. - "%a%"?