Sqlite3 JS 更新可变数量的字段

问题描述 投票:0回答:1

我正在开发 sqlite3 数据库。我想创建一个包装函数来更新采用 rowid(主键)和更新对象的表条目。

const testUpdate = {
    isFavorite : true,
    rating : 4,
}

const updateMovie = function(id, update) {
    return new Promise((resolve, reject) => {
        const sql = 'UPDATE films SET isFavorite = ?, rating = ? WHERE id = ?';
        db.run(sql, update.isFavorite, update.rating, id, (err, rows) => {
            if (err)
                reject(err);
            resolve(rows);
        });
    });
}

使用

?
可以防止 SQL 注入和其他攻击,所以我知道我不应该对 SQL 使用字符串插值(这可以轻松解决我所有的问题),但是如果我希望我的更新对象具有 可变数量的属性怎么办(例如,在一种情况下,我想要更新 isFavorite、评分和 watchDate,而在另一种情况下,我只想更新 isFavorite)?

我想到了两种解决方案:

  1. 从数据库中读取条目并使用旧值作为默认值更新所有值。
  2. 如果定义了对象的每个字段,则有条件地执行多次更新。 (这可能应该在事务内完成)。

我该怎么办?

id 标题 是最爱 评分 观看日期 用户ID
2 21克 1 4 2024-03-17 1
3 星球大战 0 1
4 矩阵 0 2
5 怪物史莱克 0 3 2024-03-21 2
javascript sqlite
1个回答
0
投票

这相对简单。

首先,您要找出要更新的所有密钥:

let keys = Object.keys(update)

首先,循环遍历每个键以确保它位于有效键列表中:


const validKeys = ["title","isFavorite","rating","watchDate","userId"];
keys = keys.filter(key => validKeys.indexOf(key) != -1);

然后,循环遍历每个键来构建设置的字符串 (

x = ?, y = ?, z = ?
)

const setStr = keys.map(key=> `${key} = ?`).join(', ');

然后,获取您想要将密钥更新为的所有值:

const values = keys.map(key=> update[key]);

因为这些值代表所有

?
,所以您需要添加
id
的最终值 (
WHERE id = ?
)

values.push(id);

然后您可以使用传递的值运行 sql 语句。

db.run(`UPDATE films SET ${setStr} WHERE id = ?`, values, (err, rows)=>{
    if(err) return console.error(err)
    console.log(rows);
});

注意:你做的地方

(sql, update.isFavorite, update.rating, id,...
,应该是
sql, [update.isFavorite, update.rating, id],...
db.run 的第二个参数是一个列表。

© www.soinside.com 2019 - 2024. All rights reserved.