My database looks like this:
Table: Guilds -> guild_id, guild_name, guild_owner, guild_owner_id, guild_member_count, guild_prefix.
Table: Members -> member_id, member_name, member_disc
Table: Guildmembers -> guild_id, member_id, warning_points, chat_points
So guild_id and member_id are the values from Discord and are both PK's. My aim is to tie each member to a guild specifically, to add warning_points and chat_points.
I can populate both the Guilds table and the Members table, however, it doesn't auto-populate the Guildmembers table with the relevant data.
Upon trying to populate the table with this code:
let guiMemSQL = 'INSERT INTO Guildmembers(guild_id, member_id) SELECT Guilds.guild_id, Members.member_id FROM Guilds INNER JOIN Members ON Guilds.guild_id = Members.member_id'
con.query(guiMemSQL, (err, result) => {
if(err){ throw err }
console.log(`Updated GuildMembers Table`);
})
I get no errors. The table doesn't populate either. So either there is a flaw in my code/logic or I have not understood what I am doing correctly.
The information I am trying to get is guild_id and member_id, they are BIGINTs.
mysql will not auto-populate a many-many table, you have to INSERT the values as you would any other table. The way I did this was with the below code:
// Update GuildMembers Table
let guiID = MemberInfo.userGuildID;
const memGuiID = BigInt(guiID); // Convert String to Number
const updGMT = {guild_id: memGuiID, member_id: memIdNo };
let guiMemSQL = 'INSERT INTO Guildmembers SET ?';
con.query(guiMemSQL, updGMT, (err, result) => {
if(err){ throw err }
console.log(`Updated GuildMembers Table`);
})
The use case of parameterised queries here, although not question specific are important to help combat the risk of sql injection attacks. And would be seen as good practise.
If anyone does know of a way to get the fields to auto-populate, please share!.
Currently I shall leave what I did to resolve this, In case others have a similar issue.
Related
I'm making a program where the user will enter data into inputs on a website. This information will then be relayed back to the server, using socket.io, and will be stored in a database. I am using this library to access MySQL from Node.js. Usually, when the user inputs the data, it is fine. But when the data includes single quotations, things aren't working. Here's an example:
let data = "LET'S GO";
// this is the data that the user inputs
// if it has single quotations in it, the code doesn't work
// otherwise it does
connection.getConnection(function(error, conn) {
if (error) throw error; // if there's an error while connecting, throw it
conn.query(
`INSERT INTO table_name (column) VALUES ('${data}')`, // make query with this MySQL call
function(err, result) {
conn.release();
if (err) throw err; // if there's an error with the call, throw it. Usually where my error comes
}
)
})
As commented in the code above, if the data variable has single quotations in it, the MySQL will return an error like the following:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 's go.' at line 1
After initially running into this error, I've been looking for a solution. On this page, it says to use mysql.escape(), connection.escape() or pool.escape() to eliminate this issue. I've looked all over Stack Overflow solutions, but they all seem to point back to this. The issue with this solution is that the data is entered into the MySQL query with two single quotations around it. Therefore, the query looks a bit like this:
INSERT INTO table_name (column) VALUES (''DATA_HERE'')
Instead of:
INSERT INTO table_name (column) VALUES ('DATA_HERE')
In addition, I've looked at similar issues with mysql.escape(), connection.escape(), and pool.escape(), but they have been of no help because most of them do not have direct solutions.
Is there any OTHER way to escape these single quotations (apostraphes), if they were to appear in the data that the user inputs?
Thank you in advance. Any and all help is appreciated.
Alright, so it looks like I found an answer. My query has to be formatted in a way similar to prepared statements (thanks to #danblack for this). It should be done as such:
conn.query(
`INSERT INTO table_name (column) VALUES (?)`,
[data],
function(err, result) {
conn.release();
if (err) throw err;
}
)
I replaced '${data}' with ? and, in the next argument of the conn.query() function, I gave the value that ? should be replaced with.
If there is more than one data value that needs to be "escaped" in a similar way, you would do this:
conn.query(
`INSERT INTO table_name (column1, column2, column3) VALUES (?, ?, ?)`,
[data1, data2, data3],
function(err, result) {
conn.release();
if (err) throw err;
}
)
If anyone else happens to have a similar pending question, I hope this answers.
Note: this way of "escaping" doesn't only work with INSERT statements. I believe it can be used for all other queries.
I'm trying to retrieve some data from a mysql database with the code:
app.get("/api/getStudentsFromClass", async(req,res) => {
const currentClassClicked = req.query.currentClassClicked
connection.query(
"SELECT * FROM ?",
[currentClassClicked],
(err,result) => {
if(result){
console.log(result)
}
if(err){
console.log(err)
}
}
)
})
The front end:
const currentClassClicked = localStorage.getItem("currentClassClicked")
const [students, setStudents] = useState("")
Axios.get("http://localhost:1337/api/getStudentsFromClass", {
params: {currentClassClicked}
}).then((response) => {
setStudents(response.data.message)
console.log(students)
})
However it says there's an error in mysql statement and shows that the statement is this
sql: "SELECT * FROM '13a1'"
I don't know why it's '13a1' and not 13a1.
Thank you
Because you're telling that 13a1 is a string (as opposed to a table name):
"SELECT * FROM ?",
[currentClassClicked],
The whole point of prepared statements and bound parameters is to separate code from data.
The only way to secure your current design is to have a hard-coded list of tables, verify that received input maps a known table and build SQL dynamically, as in "SELECT * FROM " + currentClassClicked. But the overall idea looks strange. One would expect to find a master table with all classes and a child table with the information identified by class ID.
As per the follow-up comments, you don't create a new table for each student—there's no reason to handle classes different. However, if you want to keep your current design you'll have to hard-code tables in the application code or assume that it isn't secure and PII data could eventually be exposed.
I extracted data from database in excel format using sql join query. I modified few columns data in to that exce sheet. I want update modified data into database using respective row ids.
When I iterate stack: Error: aborted is thrown.
below is my code
sql.connect(db, async (err)=> {
if (err)
console.log(err);
var request = new sql.Request();
var workbook = XLSX.readFile('2021-08-30-202129.xlsx');
var sheet_name_list = workbook.SheetNames;
var xlData = XLSX.utils.sheet_to_json(workbook.Sheets[sheet_name_list[1]]);
console.log(xlData);
xlData.forEach(async (item)=>{
let returnquery = await ` UPDATE [billing] SET notes='${item.notes}' WHERE id='${item.id}'`
request.query(returnquery, function (err, result) {
if (err) {
console.log(err)
}
else{
console.log('result', result);
}
sql.close();
});
})
});
I typically use the workbench app, and open a query window, to ensure I have the correct SQL syntax. (console.log your sql statement right before you call the DB, then copy it over to the workbench).
I usually have some small typo issue, and this allows me to easily figure that out, then go back to the code and fix the error.
I also think you have issues with having ' by your variables. those should be removed since you're already in `` style. SQL will misinterpret those.
I want to store the amount of money each player has, but I can't figure out how to have a custom variable for each discord user in the server. Any kind of help would be useful, thank you.
Required Dependencies: sqlite
Well considering that this question is very general, I'll give a fairly general answer. Knowing that you're using discord.js ...
One way you can complete your goal, is by creating an sqlite database. Note: this does not involve variables. To do this, you will have to require sqlite as a dependency:
const sql = require("sqlite");
Once completed this, you can create the file, the database will be in:
sql.open("./database.sqlite")
After which you will set up the table for the users:
sql.run("CREATE TABLE IF NOT EXISTS userData (userId TEXT, money INTEGER)").then(() => {
sql.run("INSERT INTO userData (userId, money) VALUES (?, ?)", [<user id object here>, 0]);
});
That would create a database you can use to store information about each user in your guild.
After which to update their balance follow this format (example):
sql.get(`SELECT * FROM userData WHERE userId = ${msg.author.id}`).then(row => { //the row is the user's data
if(!row) { //if the user is not in the database
sql.run("INSERT INTO userData (userId, money) VALUES (?, ?)", [`${guildId}`, <user id object here>, 0]); //let's just insert them
msg.channel.send("Registered.")
} else { //if the user is in the database
sql.run(`UPDATE userData SET money = ${row.money + 100} WHERE guild = ${msg.guild.id}`)
}
});
If there are issues in the code provided or errors, feel free to comment or contact me :)
Objects/Dictionaries are perfect for this exact situation. You can create an object and create entries for each user using their userId.
var bankBalances = {};
bankBalances[pruina.id] = 5;
bankBalances[ekw.id] = 3;
though of course without knowing the library you're using, I can only give you pseudocode.
I have just learnt about SQL injection so I am making my queries a little more safe, everything has worked out so far except when I use update.
var sql = 'UPDATE Clients SET LastAccessDate= ? WHERE ClientID= ?';
var values = [
[timeStamp[1], ClientID[1]],//timeStamp=1473674800015, ClientID= 123
[timeStamp[2], ClientID[2]],
[timeStamp[3], ClientID[3]],
[timeStamp[4], ClientID[4]]
];
connection.query(sql, [values], function(err) {
if (err) {
throw err;
console.log("Error updating Last Access times");
}
else if(!err){
connection.end();
}
});
The connection to the database was done correctly, all column names are correct and arrays for the variables is correct, but I get an error that the syntax is wrong for update and I don't know where to look for the correct answer as my searches have been unsuccessful so far. What is the correct syntax for update and where can I look to find the syntax for other queries? The timestamp is a Bigint and the clientID is a unsigned int. Also ClientID is unique. Using nodejs and mysql database.