【问题标题】:What's a portable way to express an IN condition that acts the same as an empty list?什么是表达与空列表相同的 IN 条件的可移植方式?
【发布时间】:2018-07-01 03:50:57
【问题描述】:

例如,() 工作于sqllite3

select *
from orders
where custid = ?
and status in ()

但它在postgres 中失败:

ksysdb=# select code, applicable_objecttype 
from pssystem_ktagtype where applicable_objecttype in ();

ERROR:  syntax error at or near ")"
LINE 1: ...pe from pssystem_ktagtype where applicable_objecttype in ();

使用(null) 让postgres 很开心,而且似乎不会打扰sqllite3:

ksysdb=# select code, applicable_objecttype 
from pssystem_ktagtype where applicable_objecttype in (null);
code | applicable_objecttype
------+-----------------------
(0 rows)

但它可以在 SQL Server 和 Oracle 上运行吗? ANSI SQL 有什么要说的?我的猜测是 null 永远不会匹配任何东西(包括 null 本身),因此 in list 条件将始终评估为 false。

【问题讨论】:

  • 我认为你认为 null 永远不会匹配任何东西的假设是正确的。在 SQL 中,X IN (A, B) 等价于 (X = A) OR (X = B),这意味着在 null 的情况下,X = NULL 为 false。
  • 是的,但是其他数据库会不会在in (null) 上窒息?我可以稍后在 Oracle 上进行测试,但我现在手头没有 SQL Server,我希望它也能涵盖其他数据库。
  • 查看您的最后一条评论,MS SQL、MySQL 和 Oracle SQL 之间存在一些细微差别。我的问题是总体目标是什么,您现在正在使用哪些系统?如果你有一个带有内联 sql 的应用程序,你需要运行条件 \if \ case 语句,或者如果它在一个存储过程中,你可能需要简单地运行不同的查询
  • 我想要实现的是动态生成一个查询,无论接受值列表是否为空,该查询在语法上对于尽可能多的数据库都是正确的。它不是子查询,因为列表的内容将在应用程序级别决定。因此,例如,您可能想要一次所有shipped, delayed 订单。但只是shipped 下一个。如果什么都不选怎么办?不,它不应该返回任何东西,但也不应该导致 SQL 执行错误。注意:列表成员将通过 prepared statement 进行管理,以避免 SQL 注入问题。所以in (?,?).
  • NULL 很好。它是完全有效的 SQL,如果它是列表中唯一的东西,则评估为 UNKNOWN。但是为什么在这种情况下发送查询,因为它不会返回任何行?

标签: sql


【解决方案1】:

IN (NULL) 在 Postgres、SQL Server、Oracle、MariaDB、MySQL 和 SQLite 中应该没问题。至少我在SQL Fiddledb<>fiddle 上不会产生任何错误。

设置:

CREATE TABLE a
             (a varchar(1));
INSERT INTO a
            (a)
            VALUES ('a');
SELECT *
       FROM a
       WHERE a IN (NULL);

【讨论】:

    【解决方案2】:

    也许你可以做一个返回空列表的子查询: 选择 * 从订单 哪里 custid = ? 和(选择...)中的状态

    我不明白你想要达到什么目的,在空列表上做总是会返回 False。

    【讨论】:

    • 不,抱歉,虽然我不是反对你的人,但关键是应用程序而不是服务器决定了它想要列表中的哪些项目。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多