this is how i query to update row and it works:
const [rows, meta] = await db.query(
`
UPDATE
Portfolio
SET
title = ?,
infoText = ?,
devPeriod = ?,
tags = ?
WHERE
id = ?
`,
[title, infoText, Number(devPeriod), tags, Number(portfolioId)]
);
return rows;
but sometimes depending on what user wants i have to query to update only specific columns. For example user might want to edit only devPeriod or tags and infoText.
How do i achieve that?
I'd suggest creating an update object that specifies which fields to update and the relevant values. You can then create a query and parameters from this.
The update object can be populated based on user input.
For example:
async function updatePortfolio(db, portfolioId, update) {
const query = "Update Portfolio SET " + Object.keys(update).map(key => `${key} = ?`).join(", ") + " WHERE id = ?";
const parameters = [...Object.values(update), portfolioId];
console.log("updatePortfolio: Running query:", query);
const [rows, meta] = await db.query(query, parameters);
return rows;
}
// Add or remove fields as you require.
update = {
title: "Some Title",
infoText: "Infotext",
devPeriod: 10,
tags: "tags"
}
updatePortfolio(db, 1, update);
// Add or remove fields as you require.
update = {
title: "Some Title",
tags: "tags"
}
updatePortfolio(db, 2, update);
After asking my colleagues for help they introduced my to Knex.js to make dynamic query building easier. So I just went with it.
Have been using it for dynamic queries since then. Works pretty well for this type of task. Configuration is also easy:
import knex from 'knex';
const queryBuilder = knex({ client: 'mysql' });
export default queryBuilder;
Export it and use it anywhere in your project
Related
TypeORM is working on inserting arrays using INSERT.
I'm going to do another task using the IDs that came out as a result of insert.
At this time, the IDs that come out as a result of insert come out in the order of array when insert?
// customRepository.ts
insertArr(nameArr : {name : string}[]){
reuturn this.createQueryBuilder()
.insert()
.into(customTable)
.values(nameArr)
.execute()
}
// service.ts
const connection = getConnection();
const repository = connection.getCustomRepository('customRepository')
const arr = [{name : 'first'},{name : 'second'}]
const result =
await repository.insertArr(
arr
);
console.log('result : ', result);
//Does this result come out in the order of insert?
Thank you!!!
Is there a way to check if a particular string exists in a column in a table?
For example, I have a table 'fruits' with two columns, primary key and fruit_name and following rows
1 apple
2 orange
3 pineapple
I have a sample string named apple_shake. I need to check if a substring of this apple_shake exists. The query should return row containing 'apple'
I know how this can be done in mysql query - SQL - Query to find if a string contains part of the value in Column
But through sequelize, following has problem
var sample_fruit_string = "apple_shake";
var gsp_config = await model.fruit.findOne({where: {
fruit_name: {
[Op.like]: sample_fruit_string + '%'
}
}});
Credit to #alx for the SQL I didn't know was possible - this is how you generate the appropriate SQL with Sequelize. Note that this may not be efficient with large datasets.
const sample_fruit_string = "apple_shake";
const gsp_config = await model.fruit.findOne({
attributes: ['id'],
where: Sequelize.where(
Sequelize.fn('LOCATE', Sequelize.col('fruit_name'), sample_fruit_string),
Sequelize.Op.ne,
0
),
logging: true,
});
Generates the following:
SELECT `id` FROM `fruit` AS `fruit` WHERE LOCATE(`fruit_name`, 'apple_shake') != 0 LIMIT 1;
Sequelize has a substring operator which you could use directly to solve this.
var sample_fruit_string = "apple_shake";
var gsp_config = await model.fruit.findOne({where: {
fruit_name: {
[Op.substring]: sample_fruit_string // LIKE '%sample_fruit_string%'
}
}});
var sample_fruit_string = "apple_shake";
var gsp_config = await model.fruit.findOne({where: {
fruit_name: {
[Op.like]: `%${sample_fruit_string}%` // LIKE '%sample_fruit_string%'
// [Op.ilike]: `%${sample_fruit_string}%` // For case sensitive searching
// [Op.substring]: sample_fruit_substring // Has been depreciated in future version of sequelize.
}
}});
I have the following query to select a list of vocabulary from a Japanese dictionary.
SELECT * FROM dictionary
WHERE from_local = 1
AND (word like '%後%' or reading like '%後%')
Running this program in HeidiSQL, it works as expected. I feel like it could be a charset issue but I don't think it would work at all if this were the case. (See screenshot)
My problem occours when I try to run this query in my Node.js app. The results return empty.
I am using npm's mysql library. The dbQuery method is a helper function I made (Pastebin link)
import { dbQuery } from '../db'
const search = async(query) => {
try {
let sql = 'SELECT * FROM dictionary WHERE'
sql += ' from_local = ? AND'
sql += ' (word = ? OR reading = ?)'
const params = [1, '%'+query+'%', '%'+query+'%']
console.log('dictionary DB', {query, sql, params})
return await dbQuery(sql, params)
}
catch(err) {
console.log('search Error', err)
}
}
Soultion I was being stupid
I had forgot to change the = to LIKE in my query
I try to insert data data in mysql table with sequelize but it insert null instead of value
i m trying following below code in my file userController.js
var db = require('../../../../config/db');
var bcrypt = require('bcryptjs');
TBL_USERS = db.connection.define('users');
var usersController = {
register : function(req,res,next){
db.connection.sync().then(function(){
TBL_USERS.create({
username:req.body.username,
email:req.body.email,
password:bcrypt.hashSync(req.body.password),
role_id:2
}).then(function(insertResult){
//console.log("INSERT...............",insertResult);
let send_data = {success:true,status:200,message:"success",data:insertResult};
return res.json(send_data);
})
.catch(function(err){
console.error("query error =>",err);
return ReE(err, 200,' register fail1',err);
});
})
.catch(function(err){
console.error("sync error =>",err);
return ReE(err, 200,'register fail2',err);
});
}
module.exports = usersController;
it return success message , but it only inserted field_id, createdAt and updatedAt
NOTE: i already validate all value with express-validator so i didn't define in
TBL_USERS = db.connection.define('users');
please help me to resolve this
Need to define data types in users.js or your database model file. add two lines as bellow
username: DataTypes.STRING,
password: DataTypes.STRING
There is no reason to not working. thanks
You need to define schema with field name of table
I am migrating the database of my node.js/typescript project from Oracle to MYSQL.
My queries/dml in Oracle are all bind in this style
conn.execute('select date, name from table
where id = :ID and field = :VAR',
{ID: variable1, VAR: variable2});
When using MYSQL I found this:
connection.query('select date, name from table
where id = ? and field = ?',
[variable1, variable2]);
The second approach is worse for me because of following reasons:
i- I would to rewrite a lot of sql calls in my code
ii- I think the first approach is much more reliable, as you are not concerning of having unpredictable results due to changing in SQL
Although I found some mention to the first style here, it couldn't make it work
Any tips?
As I didn't find anything ready that could solve the issue, I tried to solve the problem. Maybe this could be helpful.
first, this code gets an Oracle bind interface type like {ID: 105, DEPT: 'MKT'} and a query like 'select * from emp where id = :ID and deptName = :DEPT' and translates them to [105,'MKT'] and 'select * from emp where id = ? and deptName = ?'
here is the code
const endBindCharacters: string = ' )=';
function prepareSQL(sql: string, binders: Object = null, valueArray: TBindArray): string {
let ich: number = 0;
let bindVariable: string;
if (! binders) {
if (sql.indexOf(':') > 0) {
throw new CustomError(errorCodes.connection.sqlBoundWithNoBinders,
'No binders {} in a bound SQL ' + sql);
};
return sql;
};
while ((ich = sql.indexOf(':')) > 0) {
bindVariable = '';
while (!endBindCharacters.includes(sql[++ich]) && ich < sql.length) {
bindVariable += sql[ich];
};
if (binders[bindVariable]) {
valueArray.push(binders[bindVariable]);
} else {
throw new CustomError(errorCodes.connection.bindVariableNotInBinders, ' Bind variable ' + bindVariable +
' não encontradada no binders {} da expressão:\n' + sql)
};
sql = sql.replace(':' + bindVariable, ' ? ');
};
return sql;
};
This is the wrapper. It will get a Promise from the callback.
export async function executeSQL (conn: TConnection, sql: string,
binders: Object = {}): Promise<TReturn> {
let bindArray: TBindArray = [];
sql = prepareSQL(sql, binders, bindArray);
console.log(sql, binders, bindArray);
return new Promise<TReturn>(function(resolve, reject) {
conn.query(sql, bindArray , function(err: db.IError, results: TReturn) {
if(err) {reject(err)}
else {resolve(results)};
});
});
};