当我看到该列存在时,SQLite 错误“没有这样的列”

Posted

技术标签:

【中文标题】当我看到该列存在时,SQLite 错误“没有这样的列”【英文标题】:SQLite error "No such column" when I can see that the column exists 【发布时间】:2020-11-23 00:19:59 【问题描述】:

这里的背景故事是我正在开发一个 Discord 机器人。要求的功能之一是让它高球侮辱。我认为让用户能够通过 SQLite 3 数据库(特别是 Better-sqlite3)添加侮辱会很有趣,并且在这样做时,我还想跟踪每次侮辱的最近使用情况(这是为了将来在“insultinfo”类型命令中使用)。我添加了一个名为“lastUsed”的 DATETIME 列。添加新的侮辱时,我的insultadd 命令能够写入此列。问题是当我调用侮辱命令时,它应该说侮辱,然后用当前日期更新 lastUsed 字段。粘贴下面的代码。

问题是我收到一个错误,上面写着“SQLiteError:没有这样的列:”,然后它会打印日期值,即使我正在尝试更新 lastUsed 列并且我不知道如何解决这个问题。问题必须在 db.prepare 语句中,我只是没有看到我需要做些什么来解决它。

execute(msg, args) 
    const SQLite = require("better-sqlite3");
    const db = new SQLite('./userinputs.sqlite');
    // Check if the table "userinputs" exists and has content from this guild.
    const table = db.prepare(`SELECT count(*) FROM userinputs WHERE (guild = $msg.guild.id OR guild = 'Global') AND type = 'insult';`).get();
    if (!table['count(*)']) 
        return msg.channel.send("I don't have any insults yet");
    
    var date = new Date();
    const rawInsult = db.prepare(`SELECT * FROM userinputs WHERE type = 'insult' AND (guild = $msg.guild.id OR guild = 'Global') ORDER BY RANDOM() LIMIT 1;`).get();
    const insult = rawInsult['content'];
    const insultID = rawInsult['row'];
    if (args[0]) 
        var target = args[0];
     else 
        var target = msg.author.username;
    
    if (insult.includes('')) 
        var finalInsult = insult.replace('', target);
     else 
        var finalInsult = target + ' ' + insult;
    
    msg.channel.send(finalInsult);
    db.prepare(`UPDATE userinputs SET lastUsed = "$date" WHERE row = $insultID;`).run();
,

【问题讨论】:

我不确定是否需要更多信息,但如果它有助于解释为什么存在一些代码,我将添加幸运饼干和魔术 8 球命令,两者其中将有一个全局响应基线(在机器人所在的所有服务器上工作),并允许用户添加自定义响应,这些响应只会显示在添加响应的公会中。理想情况下,所有这些我都想跟踪最近的使用情况,以便管理员可以针对上次使用运行 info 命令来查看是谁添加了它。 我刚刚尝试将 db.prepare 语句更改为 db.prepare('UPDATE userinputs SET lastUsed = ? WHERE row = ?').run(date,insultID); 并收到以下错误:TypeError: SQLite3 can only bind numbers, strings, bigints, buffers, and null date 是一个Date,因此无法绑定...正如它所说,您只能绑定数字、字符串、bigint 和缓冲区。根据您在数据库中存储日期的方式,您可能希望改用date.valueOf()Math.floor(date.valueOf() / 1000)date.toISOString() 【参考方案1】:

我想我明白了。我最终使用了 date.toString() ,它似乎已经完成了这项工作。我在更新 db.prepare 语句后收到的错误消息表明它没有将该日期变量视为可以使用的东西,因此 .toString() 解决方法。我必须对此进行测试,看看这是否会影响我对该列进行排序的能力,因为这对我来说仍然是一个新事物,但至少命令本身正在工作并且数据库表正在更新。

如果有人在这里看到我的做法可能是愚蠢的,我愿意接受更多反馈。

更新:经过进一步测试,设置 date = Math.floor(new Date() / 1000) 在我的情况下效果更好。

【讨论】:

如果始终是当前日期,您可以使用SQLite's now:db.prepare("UPDATE userinputs SET lastUsed = DATETIME('now') WHERE row = ?").run(insultID) 我什至不知道有 now,直到,好吧,now。谢谢!

以上是关于当我看到该列存在时,SQLite 错误“没有这样的列”的主要内容,如果未能解决你的问题,请参考以下文章

无法从 SQLite 检索数据说 android (Eclipse) 中不存在该列

如何从 sqlite 游标中获取列值?

已验证的现有列上的 SQLite 数据库“没有此类列”错误

Kivy Android Sqlite3使应用程序崩溃时出现“没有这样的模块”错误

SQLite3 数据库 - 没有这样的排序规则错误

使用 SQLite“没有这样的表”测试 NHibernate - 生成模式