在nodejs上使用sqlite准备好的语句进行隐式“行值滥用”错误

问题描述

我正在编写一个简单的模型包装程序,而我准备的两个语句将无法编译。语言是JavaScript(nodejs),使用sqlite3。这两个语句都是删除操作,我无法弄清楚它们出了什么问题。其他所有语句(创建读取更新)都可以编译。

这是台词

this[CacheSymbol].deleteSettings = await this.driver.prepare(`DELETE FROM Model_Settings`)
this[CacheSymbol].deleteSettingByName = await this.driver.prepare(`DELETE FROM Model_Settings WHERE key = ?`)

它们都失败(我尝试注释掉另一个),并出现相同的错误sqlITE_ERROR: row value misused

为完整起见,以下是整个功能

async statements() {
    if(!this[CacheSymbol]) {
        this[CacheSymbol] = {}  
        this[CacheSymbol].insertBooleanSetting = await this.driver.prepare(`INSERT INTO Model_Settings (key,valueType,booleanValue) VALUES (?,?)`)
        this[CacheSymbol].insertIntegerSetting = await this.driver.prepare(`INSERT INTO Model_Settings (key,integerValue) VALUES (?,?)`)
        this[CacheSymbol].insertDoubleSetting = await this.driver.prepare(`INSERT INTO Model_Settings (key,doubleValue) VALUES (?,?)`)
        this[CacheSymbol].insertStringSetting = await this.driver.prepare(`INSERT INTO Model_Settings (key,stringValue) VALUES (?,?)`)
        this[CacheSymbol].insertBufferSetting = await this.driver.prepare(`INSERT INTO Model_Settings (key,bufferValue) VALUES (?,?)`)
        this[CacheSymbol].getAllSettings = await this.driver.prepare(`SELECT * FROM  Model_Settings`)
        this[CacheSymbol].getSettingsByName = await this.driver.prepare(`SELECT * FROM Model_Settings WHERE key = ?`)
        this[CacheSymbol].updateBooleanSettingByName = await this.driver.prepare(`UPDATE Model_Settings SET booleanValue = ? WHERE key = ?`)
        this[CacheSymbol].updateIntegerSettingByName = await this.driver.prepare(`UPDATE Model_Settings SET integerValue = ? WHERE key = ?`)
        this[CacheSymbol].updateDoubleSettingByName = await this.driver.prepare(`UPDATE Model_Settings SET doubleValue = ? WHERE key = ?`)
        this[CacheSymbol].updateStringSettingByName = await this.driver.prepare(`UPDATE Model_Settings SET stringValue = ? WHERE key = ?`)
        this[CacheSymbol].updateBufferSettingByName = await this.driver.prepare(`UPDATE Model_Settings SET bufferValue = ? WHERE key = ?`)
        this[CacheSymbol].deleteSettings = await this.driver.prepare(`DELETE FROM Model_Settings`)
        this[CacheSymbol].deleteSettingByName = await this.driver.prepare(`DELETE FROM Model_Settings WHERE key = ?`)
    }
    return this[CacheSymbol]
}

有人知道这里发生了什么吗?我该如何解决?任何帮助都将不胜感激

编辑

我直接使用sqlite3(没有一个包装器)在节点REPL中尝试了此操作,并且遇到相同的错误。我想这可能与我设置的触发器有关,所以我将添加整个表定义。

settings.model.sql

CREATE TABLE IF NOT EXISTS Model_Settings (
    key TEXT UNIQUE NOT NULL,valueType TEXT NOT NULL,booleanValue INTEGER,integerValue INTEGER,doubleValue REAL,stringValue TEXT,bufferValue BLOB,lastUpdate DATETIME
);
CREATE UNIQUE INDEX IF NOT EXISTS index_Model_Settings_key ON Model_Settings (key);
CREATE TRIGGER IF NOT EXISTS Model_Settings_trigger_update_timestamp AFTER UPDATE ON Model_Settings 
BEGIN
    UPDATE Model_Settings SET lastUpdate = DATETIME('Now') WHERE key = NEW.key;
END;
CREATE TRIGGER IF NOT EXISTS Model_Settings_trigger_insert_timestamp AFTER INSERT ON Model_Settings 
BEGIN
    UPDATE Model_Settings SET lastUpdate = DATETIME('Now') WHERE key = NEW.key;
END;
CREATE TRIGGER IF NOT EXISTS Model_Settings_trigger_insert_valueType BEFORE INSERT ON Model_Settings
BEGIN
    SELECT
        CASE
            WHEN NEW.valueType NOT IN (0,1,2,3,4) THEN
                RAISE ( ABORT,'Invalid valueType for Setting' )
        END;
END;
CREATE TRIGGER IF NOT EXISTS Model_Settings_trigger_delete_valueType BEFORE DELETE ON Model_Settings
BEGIN
    SELECT
        CASE
            WHEN OLD.valueType NOT IN ((0,4)) THEN
                RAISE ( ABORT,'Invalid valueType for Setting' )
        END;
END;

一个编辑 因此,这是一个可以运行的脚本(与上述sql一起使用)来重现错误(希望不仅仅是我)

const sqlite3 = require('sqlite3')
const database = new sqlite3.Database(':memory:')
database.exec(require('fs').readFileSync(require('path').resolve(__dirname,'./server/lib/model/settings.model.sql'),{encoding: 'utf8'}))
//above line loads sql as string
database.prepare(`DELETE FROM Model_Settings`)

解决方法

好吧,我是笨蛋。在执行过程中,生成sql文件的生成器另加了一个括号,而我实在是看不见它。因此,回答:

Model_Settings_trigger_delete_valueType触发器在(0,1,2,3,4)周围有一组额外的括号,该错误发生在我生成这些sql文件(通过我自己的,错误的,脚本的)前几天,但不是直到我开始运行测试时才注意到。这个故事的寓意是编写程序defensively,并假设错误是您自己的,然后再假设错误。谢谢大家,我希望这可以充当铁靴,其他人的脚步不及我