I have a weird problem I encountered using Postgresql and Node. I would like to use LIKE in my query together with % at the beginning and end of searched term. I have no issue using it in the plain SQL:
THIS WORKS:
SELECT * FROM vehicle WHERE module_imei LIKE '%searchterm%' OR custom_id LIKE '%searchterm%'
However, using it in Node is a bit of challenge. I haven't been successful in resolving it yet:
THIS DOES NOT WORK:
getVehiclesSearch: async function({ search }) {
let response;
try {
response = await pool.query(`SELECT * FROM vehicle WHERE module_imei LIKE %$1% OR custom_id LIKE %$1%`, [search]);
if(response) return response.rows;
} catch(error) {
// handle error
console.error(error);
// do not throw anything
}
},
Doing above will produce: syntax error at or near "%"
SELECT * FROM vehicle WHERE module_imei LIKE '%${$1}%' OR custom_id LIKE '%${$1}%
Doing above will produce: $1 is not defined
SELECT * FROM vehicle WHERE module_imei LIKE '%$1%' OR custom_id LIKE '%$1%'
Doing above will produce: bind message supplies 1 parameters, but prepared statement "" requires 0
I kind of struggle factoring the % in so it won't crash the query. Simply run out of ideas after trying above and variables of those. Thanks for your kind help.
This has been already answered over here:
Go postgresql LIKE query
In this particular case:
response = await pool.query(`SELECT * FROM vehicle WHERE module_imei LIKE '%'||$1||'%' OR custom_id LIKE '%'||$1||'%'`, [search]);
This would work.
You are missing single quotes, also I don't recognize a db adapter you use, but you can use template literals (watch out for sql injection!!!)
response = await pool.query(`SELECT * FROM vehicle WHERE module_imei LIKE '%${search}%' OR custom_id LIKE '%${search}%'`);
Related
I am setting up my first REST API to query a Postgres database I set up. I have two CRUD methods that currently work that query for all rows in a table and for rows where ID = something, respectively.
The problem I'm having occurs when trying to query when the request parameter is a String. Here is the error I'm getting:
error: invalid input syntax for type integer: "NaN"
Here is how I've set up my GET route and endpoint URL:
const getShowByTitle = (request, response) => {
const title = request.params.title
pool.query('SELECT * FROM show WHERE title = $1', [title], (error, results) => {
if (error) {
throw error
}
response.status(200).json(results.rows)
})
}
app.get('/show/:title', getShowByTitle)
Expected result is that sending a GET request using a show title as a parameter (String) returns a JSON response of just that show.
Any help or direction to some useful resources would be greatly appreciated. Thank you.
There are some issues here, first in SQL the name of the tables should be in plural "shows", second you are making the select without quotes, you need something like:
"SELECT * FROM show WHERE title = '$1'"
Third, since the user can use uppercase and down cases you need a more robust way to search for text using LIKE, ILIKE and ~, ~* operators.
https://www.2ndquadrant.com/en/blog/text-search-strategies-in-postgresql/
Fourth and more important, you are not filtering the string and you are at risk of suffering an SQL injection because "UPDATE admins SET password='newsom22th88';" is going to be executed in your database.
After some debugging my original code wasn't working because I had multiple verb-route matches. I solved the issue by creating a new unique verb-route match. Below is my complete code for querying using a String. Aarkerio's other points still hold; I need to alter my code to avoid SQL injection as well as create a more robust search.
const getShowByTitle = (request, response) => {
const title = request.params.title
pool.query('SELECT * FROM show WHERE title = $1', [title], (error, results) => {
if (error) {
throw error
}
response.status(200).json(results.rows)
})
}
const query= 'SELECT * FROM TEST WHERE "partitionId" = \'sr\' AND "name" LIKE \'%?%\'';
db.execute(query, ['B']).then(function(res) {
console.log(res);
}).catch(function(error) {
console.log(error);
});
I was not able to select data based on the pattern specified in the array.What is the exact way using CQL pattern matching with nodejs.I am getting "Invalid amount of bind variables" error.
NOTE: db has all the connection parameters
I think that you need to use following instead
const query= 'SELECT * FROM TEST WHERE "partitionId" = \'sr\' AND "name" LIKE ?';
db.execute(query, ['%B%']).then(function(res) {
...
P.S. Do you have corresponding indices built that support the LIKE expression? Cassandra doesn't work the same way as "standard" SQL databases.
I am using pg-promise package with Nodejs to execute PostgreSQL queries. I want to see the queries executed. Only specific queries, say, just one query that I want to debug.
I can see that one recommended way is to use the pg-monitor to catch the events and log them as mentioned here in the examples documentation.
Without using pg-monitor, is there a simple way to just print the prepared query that is executed. I can't see it in the docs.
Example:
db.query("SELECT * FROM table WHERE id = $/id/", {id: 2})
How to print this query to yield?
SELECT * FROM table WHERE id = 2
is there a simple way to just print the prepared query that is executed...
A query in general - yes, see below. A Prepared Query - no, those are by definition formatted on the server-side.
const query = pgp.as.format('SELECT * FROM table WHERE id = $/id/', {id: 2});
console.log(query);
await db.any(query);
And if you want to print all queries executed by your module, without using pg-monitor, simply add event query handler when initializing the library:
const initOptions = {
query(e) {
console.log(e.query);
}
};
const pgp = require('pg-promise')(initOptions);
I want to do a query that would look like this :
"Select * FROM ... WHERE name in ?" which would be equal to
"Select * FROM ... WHERE name in 'joe','william', ..."
Would there be a way to do something like that?
Model.query(query, array, function(err, result) {...});
I tried the following :
string = array.join("','")
Model.query(query, string, function(err, result) {...});
But then here is the result I have (the backslashes appear due to the single quotes):
Select * FROM ... WHERE name in \'joe\',\'william\',..."
Simple queries
As #Raphael mentioned, for simple queries you can use Model.find(), relevant docs section.
Queries with join
For queries involving joins, you can use find.populate(), docs for populate. Example:
Model.find().where({
attr : [your array]
}).populate('association').exec(your callback);
Very complicated queries
For more complicated queries where not even populate is enough you can indeed use .query() (documentation) but I think you may have gotten the syntax wrong. The second argument is an array. Example:
var title = "The King's Speech";
Movie.query('SELECT * FROM movie WHERE title = $1', [title], function(err, results) {})
If you are using Waterline (it should be the case if your are creating a sails app) just do:
Model.find().where({
attr : [your array]
}).exec(your callback);
I would like to use sequelize in order to produce simple query, kind of:
SELECT * FROM `Products`
WHERE `Product`.`oldPrice` > `Product`.`newPrice`
At the moment I do kind of ugly raw query, like:
database.Product.find({ where: '`Product`.`oldPrice` > `Product`.`newPrice`' })
It is not really bad practice or something, but I wonder whether I have not missed a paragraph amidst the documentation which would introduce me to a cleaner form, like for example mongo function expression (see: http://mongoosejs.com/docs/api.html#query_Query-%24where).
database.Product.find({ where: function () {
return (this.oldPrice > this.newPrice);
});
Is there a shortcut of such kind, or will I have to keep on writing SQL in such cases?
Thanks in advance.
Product.find({
where: {
oldPrice: {
gt: sequelize.col('newPrice')
}
}
});