其中 col 在查询中,以空数组作为参数



从示例 where-col-in 示例和此答案中,WHERE IN子句应具有使用以下语法的参数查询

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

其中数据是一个数组。

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

SELECT * FROM users WHERE id IN ()

这是一个语法错误。

请考虑以下语句:

  • 这行得通

    const x = await db.any('SELECT * FROM table WHERE id IN ($1:csv)', [[1, 2, 3]]);
    
  • 这不起作用

    const y = await db.any('SELECT * FROM table WHERE id IN ($1:csv)', [[]]);
    

squel库报告的类似错误提供了有关knex和 Rubysequel在这种情况下的行为方式的答案。

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


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

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

拥有WHERE col IN查询的最佳方法应该是什么,这些查询也可以将空数组作为参数处理?

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

CSV 过滤器是通用的,它可以在各种上下文中用于生成查询。因此,当您专门将其用于IN ($1:csv)时,它不知道它,并再次产生通用输出。

根据我在这个问题中留下的评论,正确的方法是检查数组中是否有任何数据,如果没有 - 根本不执行查询。首先,查询将是无效的,即使您使用一些空逻辑修补它,也意味着它不会生成任何结果,并且执行此类查询会浪费 IO。

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

常见答案

这是一个错误还是我做错了什么?

不是错误,而是大多数SQL框架的缺陷。处理这些参数非常困难,因此大多数框架只是保留空列表以生成无效的 SQLXXX in ()

是否有适用于这两种情况的替代语法。

一个简单的方法是:

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

knexsequel呢?

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

  • 其中 (id!=id) 或 ...
  • 其中 (1=0) 或 ...
  • 其中 (1!=1) 或 ...
  • 凡是假的或...

我个人不喜欢id!=id:)

对于某些框架

您可以查看其手册,看看是否有某种方法可以处理空列表,例如:框架可以用不存在的值替换空列表吗?

最新更新