Node SQL Server IN query not working with request params - javascript

I want to run a query in Node SQL Server which is using IN clause. This is the string used for querying 'a','b','c'. This code works fine, but user is passing data so, I can't use it. May lead to attacks:
const dbResult = await request.query(`
SELECT OrderID, ParentSKURefNum, SKURefNum, OrderCompleteTime
FROM ${tables.ORDERS}
WHERE OrderID IN (${idsWithQuotes})
`);
I want to use request.input('OrderIDs', ids) and then code will be like this:
request.input('OrderIDs', ids);
const dbResult = await request.query(`
SELECT OrderID, ParentSKURefNum, SKURefNum, OrderCompleteTime
FROM ${tables.ORDERS}
WHERE OrderID IN (#OrderIDs)
`);
But the code above always shows: No data found. What am I doing wrong? In second situation I also tried removing first and last quote from the string assuming request automatically adds it.
Thanks for your help!

I'm using SQL Server 2012 which doesn't support STRING_SPLIT function to split CSV into some sort of table which then IN operator operates on.
I found it on stack overflow that we can split the values using XML which I didn't really understand but did the trick.
SELECT OrderID, ParentSKURefNum, SKURefNum, OrderCompleteTime
FROM ${tables.ORDERS}
WHERE OrderID IN (
SELECT Split.a.value('.', 'NVARCHAR(MAX)') DATA
FROM
(
SELECT CAST('<X>'+REPLACE(#OrderIDs, ',', '</X><X>')+'</X>' AS xml) AS STRING
) AS A
CROSS APPLY String.nodes('/X') AS Split(a)
)

Related

How do I prevent sql injection on a WHERE IN request with parameterized query? [duplicate]

I am trying to workout how to pass in a comma sepated string of values into a postgres select within in clause query using node-postgres but unfortunately can't seem to get it working and can't find any examples.
I have the following code:
function getUser() {
let inList = "'qwerty', 'qaz'";
const result = await pgPool.query("SELECT name FROM my_table WHERE info IN ($1)", [inList]);
if (result.rowCount == 1) return result.rows.map(row => row.name)
return false
}
Basically want the end result query to process:
SELECT name FROM my_table WHERE info IN ('qwerty', 'qaz')
Unsure if this is actually the correct way of doing this with pgPool?
The right way is in the FAQ on Github --> https://github.com/brianc/node-postgres/wiki/FAQ#11-how-do-i-build-a-where-foo-in--query-to-find-rows-matching-an-array-of-values
You should be able to do it that way :
pgPool.query("SELECT name FROM my_table WHERE info = ANY ($1)", [jsArray], ...);

Filtering in join in supabase

Im using supabase with a database which have 2 tables (that are implicates in this issue).
Tables are teachers and users. Both have ID and id_teacher/id_user respectively.
Im working in a query where i need to get all teacher, joining in users table, where theres a image column.
I need just to get the teachers where the user have an not null image.
const query = supabase.from(`teachers`).select(
`
*,
id_user(
image
)
`
)
This query works to get teachers joining in users table. Because i get my wanted response.
This is a short example.
{
"id": 560,
"teacher_experience": 9,
"id_user":{
"image": "example-image.jpg"
}
}
The trouble is when i try to use some filter to avoid null images.
query.not('id_user.image', 'eq', null)
query.not('id_user.image', 'in', null)
query.ilike('id_user.image', 'null')
Are just an examples o filters tha i tryed for avoid the teachers which user.image have a null value.
Because, i want to NOT GET the entire item, but i get an item wiht a id_user = null
{
"id": 560,
"teacher_experience": 9,
"id_user": null // In this case image is null but still giving me the user
}
How is the correct form to solve this?
Just create a view in database for solve this problem. A view is a shortcut to queries and it possible apply where clause.
In sql editor on supabase https://app.supabase.io/project/{your_project_id}/editor/sql
create a new view with joins;
CREATE VIEW teachers_view AS
SELECT
t.*,
iu.image as image
FROM teachers as t
LEFT JOIN id_user as iu WHERE t.id = iu.teacher_id;
read more about left join here
and in application use
supabase.from('teachers_view').select().neq('image', null);
This has now been implemented with PostgREST 9!
Here's an example:
const { data, error } = await supabase
.from('messages')
.select('*, users!inner(*)')
.eq('users.username', 'Jane'
In your, case you'd have to do id_user!inner(image)
Source: https://supabase.com/blog/postgrest-9#resource-embedding-with-inner-joins
query.not("your_column_name", "is", "NULL")
worked for me!
odd enough, if you want to check for NULL
.filter("your_column_name", "is", "NULL")
seems to be the solution. No idea why it's not consistent
It is not possible atm.
You can see state of issue here.
Some posibilities are using views o start the query in the other table.
The Supabase client uses postgrest, so you can use all sorts of operators in your queries. See this page as a reference.
This feature came up recently with the release of the support for PostgREST 9. You have to use !inner keyword, you can now filter rows of the top-level table.
const query = supabase.from(`teachers`).select(
`
*,
id_user!inner(image)
`
).not("id_users.image", "is", "NULL")
you can try like with inner joins by using the !inner operator in select
const query = supabase.from(`teachers`).select(
`
*,
id_user!inner(
image
)
`
)

axios didn't return data with matching query string of parameter object but returns all the data in vanila JS

i have an api endpoint https://countriesnode.herokuapp.com/v1/countries.
Now i am fetching all the countries by
axios.get('https://countriesnode.herokuapp.com/v1/countries')
it returns successfully. Besides I want to fetch single countries with the country code like 'BB' .and i am trying with params and my object is like below
axios.get('https://countriesnode.herokuapp.com/v1/countries',
{
params: {
code: codeId
}
but it returns all the data like above rather than showing a single country with the following code. I also want to extract only the currency and area code. I wanted to try like this, don't know it gonna work or not.
.then(axios.spread((object) => {
console.log('Currency: ', object.data.currency);
console.log('Area code: ', object.data.emojiU);
}));
please someone help me... It took me almose the hole day for this but not able to success.
As per your comment, if you want to get the data of a specific country, you only have to append the country code id to the URL:
const codeId = 'BB';
axios.get(`https://countriesnode.herokuapp.com/v1/countries/${codeId}`)
Would give you the data for Barbados.
If you want to access the currency attribute you can do so with the code:
const codeId = 'BB';
axios.get(`https://countriesnode.herokuapp.com/v1/countries/${codeId}`).then(function(response) {
const currency = response.data.currency;
});

how to query column in SQL database via UPPER case conversion IN NODE.js javascript code..

Hi I've recently updated my SEQUELIZE node package from v3 to v4.
In my code I used to query my user table via the following sytnax
var option = {
where: ["upper(email) = ?", ssousername.toUpperCase()]
};
This would effectively query my user table converting all user emails in DB to uppercase.
When upgrading to V4 I am now given the following error thrown by the above query
Unhandled rejection Error: Support for literal replacements in the `where` object has been removed.
I cannot find any documentation as to how I should syntactically format my former query executed via a node.js backend in order to produce the following SQL query
SELECT UPPER(email) AS email
FROM dashboard."user" WHERE email='user#email.com';
Would love some help , Thanks!
They are working on deprecating all string operators I think. Under querying it seems to suggest doing it like this:
let option = {
where: sequelize.where(
sequelize.fn('upper', sequelize.col('email')),
ssousername.toUpperCase()
),
};

Couchbase Java API and javascript view not returning value for a specific Key

I am using couchbase API in java
View view = client.getView("dev_1", "view1");
Query query = new Query();
query.setIncludeDocs(true);
query.setKey(this.Key);
ViewResponse res=client.query(view, query);
for(ViewRow row: res)
{
// Print out some infos about the document
a=a+" "+row.getKey()+" : "+row.getValue()+"<br/>";
}
return a;
and the java script view in couchbase
function (doc,meta) {
emit(meta.id,doc);
}
So, when I remove the statement query.setkey(this.Key) it works returns me all the tables, what am I missing here .. How can I change the function to refect only the table name mentioned in the key
Change the map function like this:
function (doc,meta) {
emit(doc.table,null);
}
it is good practice not to emit the entire document like:
emit(doc.table, doc)
NB: This is surprisingly important:
i have tried using setKey("key") so many times from Java projects and setting the key using CouchBase Console 3.0.1's Filter Result dialog, but nothing get returned.
One day, i used setInclusiveEnd and it worked. i checked the setInclusiveEnd checkbox in CouchBase Console 3.0.1's Filter Result dialog and i got json output.
query.setKey("whatEverKey");
query.setInclusiveEnd(true);
i hope this will be helpful to others having the same issue. if anyone finds another way out, please feel free to add a comment about it.
i don't know why their documentation does not specify this.
EXTRA
If your json is derived from an entity class in a Java Project, make sure to include an if statement to test the json field for the entity class name to enclose you emit statement. This will avoid the key being emitted as null:
if(doc._class == "path.to.Entity") {
emit(doc.table, null);
}

Categories

Resources