1

我有一个完美运行的日志记录命令,唯一的问题是我无法完成off命令部分。(guildid, channel)如果公会匹配, 我需要它来删除两条记录。日志记录 这是我尝试过的。

if (args[0] === 'off') {
    message.channel.send('Logging turned off!');
    const del = db.prepare('DELETE FROM logging WHERE guildid = ?;');
    del.run({
        guildid: `${message.guild.id}`
    });
    return;

查看照片,当运行 args 时,off如果公会内容与运行命令的公会匹配,我需要它删除公会内容(495602...)和频道内容(<#5290...)。

4

2 回答 2

1

您当前的答案是使用准备好的语句的错误方法。如果你使用你的姿势,你就会向 SQL 注入敞开心扉,因为你没有将要在语句中使用的值解释为值,而是将其用作整个语句的一部分,然后运行不带参数的语句. 这意味着我可能会提供一个可能不会完全按照您的想法执行的值。

例如以下不会做任何事情,

const $rowid = "3 OR rowid = 4";
const deleteStatement = db.prepare("DELETE FROM lorem WHERE rowid = $rowid");
deleteStatement.run({$rowid});
deleteStatement.finalize();

但这会删除 rowid 为 3 或 4 的元素:

const $rowid = "3 OR rowid = 4";
const deleteStatement = db.prepare(`DELETE FROM lorem WHERE rowid = ${$rowid}`);
deleteStatement.run();
deleteStatement.finalize();

相反,请在此处查看 sqlite3 文档

您需要实际参数化您准备好的语句,如下所示:

const sqlite3 = require("sqlite3").verbose();
const db = new sqlite3.Database(":memory:");

db.serialize(function() {
    // Make the table
    db.run("CREATE TABLE lorem (info TEXT)");

    // Create some dummy data
    const insertStatement = db.prepare("INSERT INTO lorem VALUES (?)");
    for (let i = 0; i < 5; i++) {
        insertStatement.run(`My Data ${i}`);
    }
    insertStatement.finalize();

    // Delete some data
    const deleteStatement = db.prepare("DELETE FROM lorem WHERE rowid = $rowid");
    deleteStatement.run({
        $rowid: 3
    });
    deleteStatement.finalize();

    // Print elements
    db.each("SELECT rowid AS id, info FROM lorem", (err, {id, info}) => console.log(`${id}: ${info}`));
});

db.close();
于 2019-01-08T20:52:13.437 回答
0

对于将来寻找如何做到这一点的任何人来说,这就是答案。编辑:直到 2 天才能标记为答案哈哈

if (args[0] === 'off') {
message.channel.send('Logging turned off!');
db.prepare(`DELETE FROM logging WHERE guildid = '${message.guild.id}'`).run();
return;
于 2019-01-08T18:26:19.233 回答