[英]INSERT if record doesn't exist, UPDATE if exists
I am trying to make a TS3 bot with Node.js Library from Multivit4min (github) The bot should do this: (Here's table: nick (txt)| cldbid (int)| clid(txt) | lastChannel (int) btw. clid which is client id is supposed to be unique ID of client)我正在尝试使用来自 Multivit4min (github) 的 Node.js 库制作一个 TS3 机器人 机器人应该这样做:(这是表:nick (txt)| cldbid (int)| clid(txt) | lastChannel (int)客户 ID 应该是客户的唯一 ID)
Event #1 - client connects to a server:事件 #1 - 客户端连接到服务器:
Event #2 - client moves to another channel:事件 #2 - 客户端移动到另一个通道:
Event #3 - client moves to a specific channel:事件 #3 - 客户端移动到特定频道:
Generally I know how to do parts with Node but I struggle with SQL because all the time it shows some errors or doesn't work as it should.一般来说,我知道如何使用 Node 进行部分操作,但我对 SQL 感到困惑,因为它总是显示一些错误或无法正常工作。
I tried many queries but none of them worked.我尝试了很多查询,但没有一个有效。 The best I have done is some code from other thread here on stack that was 'REPLACE' and it should automatically check if it exists and then update or if doesn't exist - then insert.
我所做的最好的事情是来自堆栈上其他线程的一些代码是“REPLACE”,它应该自动检查它是否存在然后更新或者如果不存在 - 然后插入。 But always it was creating more and more copies of a record.
但它总是在创造越来越多的唱片副本。
Here's some of my code:这是我的一些代码:
ts3.on("clientconnect", event => {
sql.query("SELECT * FROM `users` WHERE `clid`= " + event.client.getUID(),
function(err, result){
if(err){
console.log(time.get() + "Error SQL: " + err)
}else{
if(row && row.length){
sql.query("REPLACE INTO users (nick, cldbid, clid, lastChannel) VALUES ('" + event.client.nickname + "','" + event.client.getDBID() + "','" + event.client.getUID() + "','" + config.lastChannel + "');",
function(err,result){
if (err){
console.log(time.get()+err)
}else{
console.log(time.get() + `Dodano użytkownika ${event.client.nickname} do bazy danych`)
}
})
}
}
})
})
I don't really want you to create whole code for me.我真的不想让你为我创建整个代码。 I am just asking for SQL queries with eventual "ifs" because as you can see, my 4th idea (I said earlier I was trying many ways) was based on SELECT and depending on a result, UPDATE or INSERT a record.
我只是要求带有最终“ifs”的 SQL 查询,因为如您所见,我的第四个想法(我之前说过我尝试了很多方法)基于 SELECT 并根据结果更新或插入记录。
Feel free to ask about vars, code etc., I got whole night..随时询问有关 vars、代码等的问题,我整晚都在..
I came up with code like here:我想出了这样的代码:
sql.query("INSERT INTO users (nick,cldbid,clid,lastChannel) VALUES('"+event.client.nickname+"',"+event.client.getDBID()+",'"+event.client.getUID()+
"',"+config.lastChannel+") ON DUPLICATE KEY UPDATE lastchannel="+event.channel.cid+";",
function(err, result){
if(err){
log.clog("Blad SQL #clientmoved: " + err)
}else{
log.clog("Pomyslnie addded/updated record of "+event.client.nickname)
}
})
And now I need help how to save 1 parameter from column x of a record to a variable.现在我需要帮助如何将记录的 x 列中的 1 个参数保存到变量中。 (int)
(整数)
To answer the original question, you want ON DUPLICATE KEY UPDATE
. 要回答原始问题,您需要
ON DUPLICATE KEY UPDATE
。 More importantly though, your code is vulnerable to SQL injection. 不过,更重要的是,您的代码容易受到SQL注入的攻击。
You should never insert the values directly into your query like that. 绝对不要那样将值直接插入查询中。 Consider the example:
考虑示例:
db.query("INSERT INTO messages (message, username) VALUES ('" + message + "', "' + username + ')");
If the username
was my authenticated username, but the message
was whatever value I typed into the UI, I could pretend to be someone else by sending a message like: I am stupid', 'someone_else') --
如果
username
是我经过身份验证的用户名,但message
是我在UI中键入的任何值,则可以通过发送类似“ I am stupid', 'someone_else') --
的消息来假装自己是别人I am stupid', 'someone_else') --
The SQL would then look like: SQL将如下所示:
INSERT INTO messages (message, username)
VALUES ('I am stupid', 'someone_else') --', 'my_username')
The --', 'my_username')
bit is treated as a comment, so it looks like someone_else
said I am stupid
. --', 'my_username')
位被视为注释,因此看起来someone_else
说I am stupid
。 This is one of the most common and easily exploitable vulnerabilities in web applications. 这是Web应用程序中最常见且最容易利用的漏洞之一。
You could parameterise your query: 您可以参数化您的查询:
db.query(`
INSERT INTO messages (message, username)
VALUES (?, ?)
`, [message, username]);
This is secure, but harder to read (in my opinion) and you have to be very careful to always do this consistently. 这是安全的,但是(我认为)更难阅读,并且必须非常小心以始终保持一致。
For your example, this would look like: 以您的示例为例:
sql.query("INSERT INTO users (nick,cldbid,clid,lastChannel) VALUES(?,?,?,?) ON DUPLICATE KEY UPDATE lastchannel=?;",
[event.client.nickname, event.client.getDBID(), event.client.getUID(), config.lastChannel, event.channel.cid],
function(err, result){
if(err){
log.clog("Blad SQL #clientmoved: " + err)
}else{
log.clog("Pomyslnie addded/updated record of "+event.client.nickname)
}
})
https://www.atdatabases.org provides database APIs that are relatively easy to use, and totally safe from this kind of attack. https://www.atdatabases.org提供了相对易于使用的数据库API,并且完全免受此类攻击。 You would just do:
您只需执行以下操作:
import connect, {sql} from '@databases/pg';
const db = connect();
db.query(sql`
INSERT INTO messages (message, username)
VALUES (${message}, ${username})
`);
to safely execute the same query. 安全地执行相同的查询。 The
sql
tag ensures the data is properly handled/escaped and @databases/pg
automatically enforces that you always add the sql
tag. sql
标记确保正确处理/转义数据,并且@databases/pg
自动强制您始终添加sql
标记。 NB there are then no quotes around the parameters. 注意,然后在参数周围没有引号。
For your example that would be something like 以您的示例为例
db.query(sql`INSERT INTO users (nick,cldbid,clid,lastChannel) VALUES(${event.client.nickname},${event.client.getDBID()},${event.client.getUID()},${config.lastChannel}) ON DUPLICATE KEY UPDATE lastchannel=${event.channel.cid};`).then(
result => log.clog("Pomyslnie addded/updated record of "+event.client.nickname),
err => log.clog("Blad SQL #clientmoved: " + err),
);
I came up with code like here: 我想到了如下代码:
sql.query("INSERT INTO users (nick,cldbid,clid,lastChannel) VALUES('"+event.client.nickname+"',"+event.client.getDBID()+",'"+event.client.getUID()+
"',"+config.lastChannel+") ON DUPLICATE KEY UPDATE lastchannel="+event.channel.cid+";",
function(err, result){
if(err){
log.clog("Blad SQL #clientmoved: " + err)
}else{
log.clog("Pomyslnie addded/updated record of "+event.client.nickname)
}
})
And now I need help how to save 1 parameter from column x of a record to a variable. 现在我需要帮助,如何将1个参数从记录的第x列保存到变量。 (int)
(int)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.