代码之家  ›  专栏  ›  技术社区  ›  BrDaHa

如何在pg promise中正确编写带有null约束的查询?

  •  1
  • BrDaHa  · 技术社区  · 6 年前

    在编写Postgres查询时,约束通常是这样编写的 WHERE a = $(a) WHERE b IN $(b:csv) 如果你知道这是一张清单。但是,如果值为 null WHERE x IS NULL

    说我可能想找行 WHERE c = 1 . 如果我知道 c 1

    db.oneOrNone(`SELECT * FROM blah WHERE c = $(c), { c })
    

    但如果 结果是 无效的 ,则查询必须为 ...WHERE c IS NULL .

    有没有可能构造一个像这样的通用查询 WHERE $(c) 其中c=1 C WHERE c IS NULL 如果 C

    1 回复  |  直到 4 年前
        1
  •  1
  •   vitaly-t    4 年前

    你可以用 Custom Type Formatting 要帮助进行动态查询,请执行以下操作:

    const valueOrNull = (col, value) => ({
        rawType: true,
        toPostgres: () => pgp.as.format(`$1:name ${value === null ? 'IS NULL' : '= $2'}`,
                                        [col, value])
    });
    

    然后,您可以将其作为格式值传入:

    db.oneOrNone('SELECT * FROM blah WHERE $[cnd]', { cnd: valueOrNull('col', 123) })
    

    使现代化

    也可以仅对值本身使用自定义格式:

    const eqOrNull = value => ({
        rawType: true,
        toPostgres: () => pgp.as.format(`${value === null ? 'IS NULL' : '= $1'}`, value)
    });
    

    用法示例:

    db.oneOrNone('SELECT * FROM blah WHERE $1:name $2', ['col', eqOrNull(123)])
    //=> SELECT * FROM blah WHERE "col" = 123
    
    db.oneOrNone('SELECT * FROM blah WHERE $1:name $2', ['col', eqOrNull(null)])
    //=> SELECT * FROM blah WHERE "col" IS NULL
    

    undefined ,但您很可能会这样做,因为 内部格式为 null

        2
  •  0
  •   gilly3    4 年前

    这是一个非常有用的替代方法,可以根据值是否为 NULL IS [NOT] DISTINCT FROM

    对于非空输入, IS DISTINCT FROM 是一样的 <> 操作人员但是,如果两个输入都为null,则返回false;如果只有一个输入为null,则返回true。同样地, IS NOT DISTINCT FROM 与相同 =

    = 使用 ,而不是 <> 使用 有别于 .

    这在比较两个列(其中任何一个都可能为空)时特别有用。

    无法使用索引,因此某些查询的性能可能很差。