select 包含 where 条件的动态列的语句

select statement with dynamic columns for where condition

我正在创建一个以 postgresql 作为后端的 nodejs 项目,我使用 pg_promise 作为查询的驱动程序

目前我必须做一个 select 语句,其中的列可能会有所不同,但都具有相同的相等条件检查,如下所示

    pg.any('select * from table where col1 = ${col1} and col2 = ${col2}',{
col1:value1,
col2:value2
});

// which generates the query shown below
// select * from table where col2 = value1 and col2 = value2;


我想要的是希望找到一种更简单的方法来生成 select 查询,其中变量的列数具有相等的条件,类似于 pg_promise 允许我们用户 helpers.update 生成更新查询。

// something like shown below
pg.helpers.select('select * from table ',{col1:value1, col2:value2})
// it shoud generate the same as the query with static columns
//select * from table where col2 = value1 and col2 = value2;

pg-promise 不包括这样的东西,因为您正在寻找的是自定义的,而不是特别通用的解决方案,因为它可能需要 AND/OR 逻辑、类型转换、使用嵌套属性等

但是,该库确实为您提供了为您自己创建此类自定义解决方案所需的所有工具。例如,如果你只需要一个对象中所有属性的 AND 条件,你可以使用这样的东西:

const andProps = obj => ({
    rawType: true,
    toPostgres: () => Object.keys(obj).map(k => {
        const val = obj[k];
        if (val === null || val === undefined) {
            return pgp.as.format(':name IS NULL', [k]);
        }
        return pgp.as.format(':name = ', [k, val]);
    }).join(' AND ')
});

以上代码使用Custom Type Formatting, plus internal format function. And it adds special provision for null/undefined, to produce IS NULL. I used :name filter here, but you can also use :alias for shorter names (see SQL Names).

用法示例

const obj = {
    id: null,
    name: 'John',
    age: 30
};

const data = await db.any('SELECT * FROM users WHERE ', [andProps(obj)]);
//=> SELECT * FROM users WHERE "id" IS NULL AND "name" = 'John' AND "age" = 30