简体   繁体   English

如果记录不存在则插入,如果存在则更新

[英]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 - 客户端连接到服务器:

  • Check if record with client.UID exists in database: yes: update its lastChannel to event.channel.channelId no: insert client.nick,cldbid,UID and event.channel.channelId检查数据库中是否存在带有 client.UID 的记录:是:将其 lastChannel 更新为 event.channel.channelId 否:插入 client.nick、cldbid、UID 和 event.channel.channelId

Event #2 - client moves to another channel:事件 #2 - 客户端移动到另一个通道:

  • Update lastChannel to event.channel.channelId将 lastChannel 更新为 event.channel.channelId

Event #3 - client moves to a specific channel:事件 #3 - 客户端移动到特定频道:

  • search record by his UID and save his lastChannel into a variable通过他的 UID 搜索记录并将他的 lastChannel 保存到变量中

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_elseI am stupid This is one of the most common and easily exploitable vulnerabilities in web applications. 这是Web应用程序中最常见且最容易利用的漏洞之一。

Solution 1 解决方案1

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)
            }
        })

Solution 2 解决方案2

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.

相关问题 Meteor 使用 $push 更新到单个记录上尚不存在的数组 - Meteor update with $push to an array that doesn't already exist on a single record 我想验证我的数据库“名称和组”中的两列是否存在显示已存在,如果不存在则插入到数据库中 - I want to validate two columns from my database “name and group” if it exists display already exists and if it doesn't exist insert into the database 将 object 添加到现有 state 如果它不存在,更新它如果存在 React state - Add object to existing state if it doesn't exist, update it if exists React state Mongodb-更新对象数组中每个对象的属性,如果不存在则插入 - Mongodb - Update property per object in array of object, Insert if doesn't exists 如果密钥不存在,则插入 object - Insert object if key doesn't exist 如果数组中不存在对象道具,则更新 - Update if object prop doesn't exist in array 类型“ {}”上不存在属性“更新”和“数量” - Property 'update' and 'quantity' doesn't exist on type '{ }' 如果有数字,请替换数字;如果不存在,请按数字结尾 - Replace digit in number if exists or push to end if it doesn't exist 如果记录已存在或PDO MySQL插入查询中不存在该记录,如何生成JavaScript警报? - How do I generate a javascript alert if the record already exists OR if it does not exist in a PDO MySQL insert query? MongoDB - 如果不存在则插入,否则跳过 - MongoDB- Insert if it doesn't exist, else skip
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM