WHERE col IN 以空数组为参数查询

WHERE col IN Query with empty array as parameter

来自示例 where-col-in example and WHERE IN 子句应具有具有以下语法参数的查询

const response = await db.any('SELECT * FROM table WHERE id IN (:csv)', [data])

其中数据是数组。

现在,当数据为空数组时,它会生成以下查询

 SELECT * FROM users WHERE id IN ()

这是语法错误。

考虑以下陈述:

squel 库报告的 similar error 回答了 knex 和 ruby 的 sequel 在这种情况下的行为。

这是一个错误还是我做错了什么?是否有适用于这两种情况的替代语法。


例如,使用 ANY 的备用查询适用于两种情况:

await db.any(`SELECT * FROM table WHERE id = ANY()`, [[1, 2, 3]]);
await db.any(`SELECT * FROM table WHERE id = ANY()`, [[]]);

WHERE col IN 查询也可以将空数组作为参数处理的最佳方式应该是什么?

常见答案

Is this a bug or am I doing something wrong?

不是错误,而是大多数 SQL 框架的缺陷。处理这样的参数非常困难,所以大多数框架只是留下空列表,因为它会生成无效的 SQL XXX in ().

Could there be an alternate syntax which works for both scenarios.

一个简单的方法是:

if(data is empty) data = [ -1 ]   //fill a non-existing id
db.any('SELECT * FROM table WHERE id IN (:csv)', [data])

knexsequel呢?

它们是查询生成器框架,因此它们有机会生成特殊的 SQL 来处理空列表。 Query Builder 框架用来处理 WHERE id in () OR ...:

的流行方法
  • 哪里 (id!=id) 或 ...
  • 哪里 (1=0) 或 ...
  • 哪里 (1!=1) 或 ...
  • 哪里为假或...
  • 等等

个人不喜欢id!=id :)

对于某些框架

您可以查看它的手册,看看是否有一些方法可以处理空列表,例如:框架可以用 non-existing 值替换空列表吗?

pg-promise 让您完全自由地生成任何您想要的 SQL,它不会以任何方式验证或控制它,因为它不是 ORM。

CSV Filter 是通用的,它可以在各种上下文中用于生成查询。因此,当您专门针对 IN (:csv) 使用它时,它并不知道,并再次生成通用输出。

根据我在 this issue 中留下的评论,正确的方法是检查数组中是否有任何数据,如果没有 - 根本不要执行查询。首先,查询是无效的,即使你用一些空逻辑来修补它,也意味着它不会产生任何结果,执行这样的查询会浪费 IO。

let result = [];
if (data.length) {
    result = await db.any('SELECT * FROM table WHERE id IN (:csv)', [data]);
}
/* else: do nothing */