如何将变量绑定到 Sequelize 字面量?

11

我有一个子查询,用于检查与源模型相关的列是否存在。

const defaultingLoans = await Loan.findAll({
    where: {
      [Op.and]: database.sequelize.literal('EXISTS(SELECT * FROM "Instalments" WHERE "Instalments"."loanId" = "Loan"."id" AND "Instalments"."status" = 'pending')')
    }
  });

查询运行良好,但理想情况下值pending不应该是固定的,所以我想在那里使用一个变量来查询不同的状态。

如何用一个变量替换pending字符串。

由于Sequelize有一种奇怪的解析连接SQL查询的方式导致出现错误,所以这里不能使用连接操作。一个例子在这里https://pastebin.com/u8tr4Xbt,我还截了一个屏幕截图在这里


1
你是否熟悉将变量连接到字符串中? - Taplar
@Hydrothermal Sequelize 字面量无法使用字符串拼接。 - proton
1
你为什么这么说?'literal()' 作为参数传入一个字符串。它的构造方式并不重要,只要是一个有效的字符串即可。literal('abc')literal('ab'+'c')都会向该方法传递相同的字符串。 - Taplar
Sequelize解析连接的SQL字符串的方式似乎存在问题,请查看以下查询:https://pastebin.com/u8tr4Xbt。当我运行该查询时,出现了以下错误图像:https://imagebin.ca/v/4RbsQOAPaxvO。 - proton
2个回答

10
您可以将defaultingLoans转换为一个接受金额的函数:
const defaultingLoans = amount => await Loan.findAll({
  where: {
    [Op.and]: database.sequelize.literal(`EXISTS(SELECT * FROM "Instalments" WHERE "Instalments"."loanId" = "Loan"."id" AND "Instalments"."amount" = ${amount})`)
  }
});

使用方法:

const loans = defaultingLoans(2000);

编辑:需要注意的是,您需要对传递到此函数中的amount进行清理或引号处理,以避免SQL注入攻击。


似乎sequelize解析连接的SQL字符串存在问题,请查看以下查询:pastebin.com/u8tr4Xbt 运行时出现的错误如下图所示:imagebin.ca/v/4RbsQOAPaxvO - proton
这是因为clause1clause2是字符串 - 当使用字符串时,您需要在连接的值周围包含引号。 - ic3b3rg
如果可以的话,您能否帮忙分享一下您所说的样例,谢谢。 - proton
我相信sequelize需要对字符串使用单引号,所以尝试使用('${clause1}', '${clause2}') - ic3b3rg
9
如果这些情况暴露给用户,请注意 SQL 注入。数额可能是'2000; DELETE FROM "Instalments";'。请注意保护数据库的安全性,以防止恶意攻击。 - Guido Dizioli
显示剩余2条评论

2
您可以将bind对象直接放置在您的查询对象中:
let status = 'Pending';
const defaultingLoans = await Loan.findAll({
    where: database.sequelize.literal('EXISTS(SELECT * FROM "Instalments" WHERE "Instalments"."loanId" = "Loan"."id" AND "Instalments"."status" = $status)'),
    bind: {status}
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接