簡體   English   中英

如果記錄不存在則插入,如果存在則更新

[英]INSERT if record doesn't exist, UPDATE if exists

我正在嘗試使用來自 Multivit4min (github) 的 Node.js 庫制作一個 TS3 機器人 機器人應該這樣做:(這是表:nick (txt)| cldbid (int)| clid(txt) | lastChannel (int)客戶 ID 應該是客戶的唯一 ID)

事件 #1 - 客戶端連接到服務器:

  • 檢查數據庫中是否存在帶有 client.UID 的記錄:是:將其 lastChannel 更新為 event.channel.channelId 否:插入 client.nick、cldbid、UID 和 event.channel.channelId

事件 #2 - 客戶端移動到另一個通道:

  • 將 lastChannel 更新為 event.channel.channelId

事件 #3 - 客戶端移動到特定頻道:

  • 通過他的 UID 搜索記錄並將他的 lastChannel 保存到變量中

一般來說,我知道如何使用 Node 進行部分操作,但我對 SQL 感到困惑,因為它總是顯示一些錯誤或無法正常工作。

我嘗試了很多查詢,但沒有一個有效。 我所做的最好的事情是來自堆棧上其他線程的一些代碼是“REPLACE”,它應該自動檢查它是否存在然后更新或者如果不存在 - 然后插入。 但它總是在創造越來越多的唱片副本。

這是我的一些代碼:

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

})

我真的不想讓你為我創建整個代碼。 我只是要求帶有最終“ifs”的 SQL 查詢,因為如您所見,我的第四個想法(我之前說過我嘗試了很多方法)基於 SELECT 並根據結果更新或插入記錄。

隨時詢問有關 vars、代碼等的問題,我整晚都在..


我想出了這樣的代碼:

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

現在我需要幫助如何將記錄的 x 列中的 1 個參數保存到變量中。 (整數)

要回答原始問題,您需要ON DUPLICATE KEY UPDATE 不過,更重要的是,您的代碼容易受到SQL注入的攻擊。

絕對不要那樣將值直接插入查詢中。 考慮示例:

db.query("INSERT INTO messages (message, username) VALUES ('" + message + "', "' + username + ')");

如果username是我經過身份驗證的用戶名,但message是我在UI中鍵入的任何值,則可以通過發送類似“ I am stupid', 'someone_else') --的消息來假裝自己是別人I am stupid', 'someone_else') --

SQL將如下所示:

INSERT INTO messages (message, username)
VALUES ('I am stupid', 'someone_else') --', 'my_username')

--', 'my_username')位被視為注釋,因此看起來someone_elseI am stupid 這是Web應用程序中最常見且最容易利用的漏洞之一。

解決方案1

您可以參數化您的查詢:

db.query(`
  INSERT INTO messages (message, username)
  VALUES (?, ?)
`, [message, username]);

這是安全的,但是(我認為)更難閱讀,並且必須非常小心以始終保持一致。

以您的示例為例:

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

解決方案2

https://www.atdatabases.org提供了相對易於使用的數據庫API,並且完全免受此類攻擊。 您只需執行以下操作:

import connect, {sql} from '@databases/pg';

const db = connect();

db.query(sql`
  INSERT INTO messages (message, username)
  VALUES (${message}, ${username})
`);

安全地執行相同的查詢。 sql標記確保正確處理/轉義數據,並且@databases/pg自動強制您始終添加sql標記。 注意,然后在參數周圍沒有引號。

以您的示例為例

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),
);

我想到了如下代碼:

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

現在我需要幫助,如何將1個參數從記錄的第x列保存到變量。 (int)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM