I'm doing a simple UPDATE with mysql2 :
UPDATE table1
SET table1.value1 = ?, table1.value2 = ?
WHERE user_id = (
SELECT user_id
FROM user
WHERE company_id = ?
)
table1 is related to the user table by user_id, but I only have the company_id so I do a subquery (probably should be a join, but thats another discussion):
const [results, buff] = await connection.execute(query, values);
return results
However, when accessing the results to make sure there are no errors and that only a single row is updated, results returns:
console.log
ResultSetHeader {
fieldCount: 0,
affectedRows: 1,
insertId: 0,
info: 'Rows matched: 1 Changed: 0 Warnings: 0',
serverStatus: 2,
warningStatus: 0,
changedRows: 0
}
But I can't access the values. If I try results.affectedRows I get
Property 'affectedRows' does not exist on type 'RowDataPacket[] | RowDataPacket[][] | OkPacket | OkPacket[]'.
The only way to make it work is to do results['affectedRows']. Any suggestions?
So I forgot to mention that this is a typescript error, and I was able to fix it by doing:
const [results, buff] = await connection.execute(query, values);
const json: any = results;
return json.affectedRows //or whatever property I want
This also works:
const [results, buff] = await connection.execute(query, values);
return json as any; //then in the calling fuction access the properties I want
Related
I try to get the Highest Number out of my Databse.
So far so good Test 1 Code:
const db = require("../../../database.js")
const test = require("./test.js")
module.exports = {
config: {
name: "try",
description: "Replies with a Number.",
},
permissions: ['SendMessages'],
owner: false,
run: async (client, message, args, prefix) => {
const test = await db.query("select Number, MemberID from numbers order by Number DESC LIMIT 3;")
console.log(test[1])
console.log(test[1].Number)
}}
But all I get out in my Console is:
Executing (default): select Number, MemberID from numbers order by Number DESC LIMIT 3;
[ { Number: 138, MemberID: '318735407963439104' } ]
undefined
So I tried another Version:
const db = require("../../../database.js")
module.exports = {
config: {
name: "stats",
description: "Replies with a Number.",
},
permissions: ['SendMessages'],
owner: false,
run: async (client, message, args, prefix) => {
const query = await db.query("select Number, MemberID from numbers order by Number DESC LIMIT 3;", async function (err, result, fields)
{
console.log(query)
const level = result[0].Number
const user = result[0].MemberID
const level1 = result[1].Number
const user1 = result[1].MemberID
const level2 = result[2].Number1
const user2 = result[2].MemberID
console.log(level)
})
}
};
But this just showed this in the Console
Executing (default): select Number,MemberID from numbers order by Number DESC LIMIT 3;
and nothing else.
I'm really depressed that nothing works, can someone help?
I have a myPlaylistSongs table, and there are Playlist_ID and Song_ID columns in it.
Each row can have only one value, and the table format is as follows.
=====================
Playlist_ID | Song_ID
---------------------
1 | 5
1 | 3
1 | 8
=====================
Customers can create a playlist and add multiple songs to it, or delete multiple songs from it.
Playlist_ID is received as Path params, and Song_ID is received as req.body.
If Song_ID is received as an array here, how can I add the Song_ID corresponding to the Playlist_ID received as Path params at once?
The query is as below.
DAO.js
const postSongs = async(playlistId, songId) => {
const playlist = await myDataSource.query(
`INSERT INTO myPlaylistSongs(playlist_id, song_id)
VALUES(?, ?)`,
[playlistId, songId],
);
return playlist;
};
I need help.
Try something like this
const postSongs = async(playlistId, songId) => {
const playlist = await myDataSource.query(
`INSERT INTO myPlaylistSongs(playlist_id, song_id)
VALUES ${songId.map((sID) => "("+sID+","+playlist_id+")").join(",")},
);
return playlist;
};
You should be able to build a single query by specifying an array of (?, ?) and for the values to be inserted:
const postSongs = async (playlistId, songId) => {
if (songId.length === 0) return []; // Empty array
let valuesString = '(?, ?),'.repeat(songId.length);
// Remove last comma
valuesString = valuesString.substring(0, values.length - 1);
const valuesArr = [];
for (const song of songId) {
valuesArr.push(playlistId);
valuesArr.push(song);
}
const playlist = await myDataSource.query(
`INSERT INTO myPlaylistSongs(playlist_id, song_id)
VALUES ${values}`,
valuesArr
);
return playlist;
};
It's really weird, I can't debug the issue. I also don't know what's causing the issue.
I have a query like below:
const sequelize = require('sequelize')
const Op = sequelize.Op
const TODAY_START = new Date().setHours(0, 0, 0, 0)
const NOW = new Date()
const data = await AssignedJob.findAll({
where: {
created_on: {
[Op.gt]: TODAY_START,
[Op.lt]: NOW
}
}
})
It generates a query like below.
SELECT `id`, `emp_id`, `zone_id`, `job_id`, `status`, `commission`, `rating`,
`created_by`, `updated_by`, `created_on`, `updated_on`
FROM `assigned_jobs` AS `AssignedJob`
WHERE (`AssignedJob`.`created_on` > '2020-03-24 00:00:00' AND `AssignedJob`.`created_on` < '2020-03-24 17:18:15');
But data is just an [] empty array.
I also tried using [Op.between]: [START_DATE, NOW], but still I didn't get any record.
I copied the same query to heidsql and ran it, I get the result there.
What's happening here? Can someone explain?
Data type of created_on and updated_on in sequelize is DATE, in the table it's TIMESTAMP
Use moment.js to format the date in 'YYYY-MM-DD HH:mm:ss'
const sequelize = require('sequelize')
const moment = require('moment');
const Op = sequelize.Op
function getDate(withoutTime) {
const date = new Date();
if (withoutTime) date.setHours(0, 0, 0, 0);
return moment(date).format('YYYY-MM-DD HH:mm:ss');
}
const TODAY_START = getDate(true); // '2020-03-24 00:00:00'
const NOW = getDate(); // '2020-03-24 17:47:41'
Problem const TODAY_START = new Date().setHours(0, 0, 0, 0) will result in Unix time i.e seconds after 1st Jan 1970
const date = new Date().setHours(0, 0, 0, 0)
console.log(date); // return seconds after 1970
const date1 = new Date();
date1.setHours(0, 0, 0, 0);
console.log(date1); // return date
I don't know the reason why that's happening, I got a fix for it. I have to use momentjs to achieve that.
const moment = require('moment')
const now = moment()
const todayAssignedJobs = await AssignedJob.findAll({
where: {
created_on: {
[Op.gt]: now.startOf('day').toString(),
[Op.lt]: now.endOf('day').toString()
},
status: 1
}
})
Same query is still being generated, but it gives result instead of giving an empty array.
SELECT `id`, `emp_id`, `zone_id`, `job_id`, `status`, `commission`, `rating`, `created_by`, `updated_by`, `created_on`, `updated_on` FROM
`assigned_jobs` AS `AssignedJob`
WHERE
(`AssignedJob`.`created_on` > '2020-03-24 00:00:00' AND `AssignedJob`.`created_on` <'2020-03-24 23:59:59')
AND `AssignedJob`.`status` = 1;
If someone got any explanation please comment or feel free to edit this answer.
I need to make a query which would be able to delete multiple rows from my table. In order to do that I've created an arrays within array with values which need to be passed to that query. Here is my code:
var deleteRooms = [ [ 3, 23 ], [ 4, 23 ], [ 5, 23 ], [ 2, 23 ]];
connection.query("DELETE FROM rate_plans_rooms WHERE room_id = ? AND rate_plan_id = ? ",
[deleteRooms],function(err,results){
if(err){return console.log(err)}
else
{
console.log('sended');
}
});
But every time I receive an error like this:
{ Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check
the manual that corresponds to your MariaDB server version for the
right syntax to use near ' (4, 23), (5, 23), (2, 23) AND rate_plan_id
= ?' at line 1
How can I fix that and send my query properly?
A solution for your problem is to use 'IN' inside your query:
var deleteRooms = [[3,23],[4,23],[5,23], [2,23]];
connection.query("DELETE FROM rate_plans_rooms WHERE (room_id, rate_plan_id) IN (?)",
[deleteRooms],function(err,results){
if(err) return console.log(err)
else console.log('sended');
});
The accepted solution did not work for me as it would give an Error: ER_OPERAND_COLUMNS: Operand should contain 2 column(s) error. Instead, this worked for me:
var deleteRooms = [[3,23],[4,23],[5,23], [2,23]];
queryArray = Array(deleteRooms.length).fill('(?)'));
connection.query("DELETE FROM rate_plans_rooms WHERE (room_id, rate_plan_id) IN ("+queryArray.join(',')+")",
[deleteRooms],function(err,results){
if(err) return console.log(err)
else console.log('sended');
});
I have the following issue to solve.
I have an IQueryable list of Invoices, each tied to an Account. Each Account can have multiple Structures, and Accounts and Structures are tied together by a table called StructureAccount. It looks like this:
Invoice ---> Account <-----StructureAccount ----> Structure
I want to query my IQueryable list of Invoices and group by Structure.StructureID or StructureAccount.StructureID. But, because any given invoice can be tied to multiple Structures the best I can get is a LIST of StructureIDs, and therefore my GroupBy is not working.
I feel like I am missing an obvious solution to this.
I should note that I understand that the data in any one Invoice would be counted multiple times if the Invoice were tied to more than one Structure, and this is "solved" by a "PercentAllocationtoStructure" value in the table StructureAccount.
I hope I did a good enough job explaining this problem. Let me know if not.
Hmmm...I might be missing something, but doesn't the following work?
var q = from i in Invoice
join a in Account
on i.AccountID equals a.AccountID
join sa in StructureAccount
on i.AccountID equals sa.AccountID
join s in Structure
on sa.StructureID equals s.StructureID
group i by s.StructureID;
I tested it on the following dummy data:
var Invoice = new [] {
new { InvoiceID = 1, AccountID = 1 },
new { InvoiceID = 2, AccountID = 2 },
new { InvoiceID = 3, AccountID = 3 },
new { InvoiceID = 4, AccountID = 1 },
new { InvoiceID = 5, AccountID = 2 },
new { InvoiceID = 6, AccountID = 3 }
};
var Account = new [] {
new { AccountID = 1 },
new { AccountID = 2 },
new { AccountID = 3 },
};
var StructureAccount = new [] {
new { AccountID = 1, StructureID = 2 },
new { AccountID = 1, StructureID = 3 },
new { AccountID = 2, StructureID = 2 },
new { AccountID = 3, StructureID = 1 },
new { AccountID = 3, StructureID = 2 },
};
var Structure = new [] {
new { StructureID = 1 },
new { StructureID = 2 },
new { StructureID = 3 }
};
And it returns:
StructureID = 2:
InvoiceID's: 1,2,3,4,5,6
StructureID = 3:
InvoiceID's: 1,4
StructureID = 1:
InvoiceID's: 3,6
I'll assume you have the following starting point:
IQueryable<Invoice> _invoices;
First, you need to get a list of all the items that you will be iterating over:
IQueryable<Account> _accounts = _invoices.Select(myInvoice => myInvoice.Account).Distinct();
IQueryable<StructuredAccount> _structuredAccounts = _accounts.SelectMany(myAccount => myAccount.StructuredAccounts);
IQueryable<Structure> _structures = _structuredAccounts.Select(myStructuredAccount => myStructuredAccount.Structure).Distinct();
Next, you need to go back and join your Structure objects to the respective Invoice objects.
For this, you'll:
Get a set of {Structure, Account} pairs:
var structureAccountJoin = _structures.Join(_structuredAccounts, _structure => structure.StructuredID, _structuredAccount => _structuredAccount.StructuredID, (structure, structuredAccount) => new { Structure = structure, Account = structuredAccount.Account });
Get a set of {Structure, Invoice} pairs:
var structureInvoiceJoin = structureAccountJoin.Join(_invoices, myObj => myObj.Account.AccountID, invoice => invoice.AccountID, (myObj, invoice) => new { Structure = myObj.Structure, Invoice = invoice});
Finally, you can group everything by the Structure object:
IQueryable<IGrouping<Structure, Invoice>> groupByStructure = structureInvoiceJoin.GroupBy(obj => obj.Structure, result => result.Invoice);
(GroupBy documentation: http://msdn.microsoft.com/en-us/library/bb534304.aspx)
Now, you can access everything as follows:
foreach(IGrouping<Structure, Invoice> groupEntry in groupByStructure)
{
Structure currentGrouping = groupEntry.Key;
foreach(Invoice inv in groupEntry)
{
// do something;
}
}
As a note, this is a very complex script that requires a lot of steps if you don't have access to the tables directly. You may want to look into creating a StoredProcedure for this instead, as it will be more efficient and you'll be able to use SQL Joins instead. If you have only an IQueryable<Invoice> to work with and access to nothing else, there is probably a design problem somewhere in your architecture.
Nevertheless, this is the way to make it work based on your requirements, if I read them correctly.