WHERE col IN Query,空数组作为参数

时间:2018-03-09 06:50:07

标签: javascript postgresql pg-promise

从示例where-col-in examplethis answer开始,WHERE IN子句应该使用带有以下语法的参数进行查询

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

其中data是数组。

现在,当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库报告的similar errorknex和红宝石sequel在这种情况下的行为方式的答案。

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

例如,使用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查询可以处理空数组作为参数的最佳方法是什么?

2 个答案:

答案 0 :(得分:3)

我是否要在这里添加我自己的答案,因为有一个已被接受,但作为pg-promise的作者,我有点必须,所以这里是...... < / p>

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

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

根据我在this issue中留下的评论,唯一正确的方法是检查数组中是否有任何数据,如果没有,则根本不生成查询。首先,查询将无效,即使您使用一些空逻辑对其进行修补,也意味着它不会生成任何结果,因此查询无论如何都是毫无意义的。

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

答案 1 :(得分:2)

常见答案

  

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

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

  

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

一个简单的方法是:

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

knexsequel怎么样?

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

  • WHERE(id!= id)OR ...
  • WHERE(1 = 0)或......
  • WHERE(1!= 1)OR ...
  • WHERE false OR ...

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

针对某些框架

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