我有一个包含ID的表,如下所示:
ID
----------------
10000V9F
10000V9O
10000VAh
10000VCB
10000VDn
10000VE9
10000VF4
10000VFE
10000VFH
10000VFW
10000VG9
现在我想从另一个没有这些ID的表中获取所有数据。因此,我创建了一个类似于这个的查询:
SELECT * from TABLE1 where ID NOT IN (...)
其中...
是通过另一个查询得到的ID列表,其中包含第一个表中所有先前提到的ID。该清单定义如下:
string idString = "'" + String.Join("'", this.GetIDsForTableNames(newTables).ToArray()) + "'";
方法GetIDsForTableNames
也可能返回一个根本不包含任何元素的空列表。在这种情况下,从上面得到的查询将导致类似这样的事情:
SELECT * from TABLE1 where ID NOT IN ('')
我希望从TABLE1
返回所有ID。但是返回NONE。但是当我触发SELECT * from TABLE1 where ID NOT IN ('a')
a
只是一个假人时,会返回TABLE1
的所有行。
那么我怎样才能适当地处理list-is-empty-case,或者为什么它不能用空列表呢?
编辑:好的,似乎有些环境不够清晰。由于我没有构建SQL字符串self(这是通过第三方工具完成的),我只能修改whereclause,这只是某种最小化的SQL(不支持子查询和连接)。这就是我使用ID IN
- 技术的原因。
答案 0 :(得分:1)
为什么它不适用于空列表?
这是因为有两件事:
<强> 1。 Oracle将空字符串视为空值
所以你的查询:
SELECT * from TABLE1 where ID NOT IN ('')
实际上相当于:
SELECT * from TABLE1 where ID NOT IN (NULL)
<强> 2。不在行为
NOT IN
子句可以简化为对列表的所有值的检查。
如果任何值的结果为TRUE
(值在列表中)或NULL
,则测试失败。
所有检查都返回NULL
,因此您的查询不会返回任何行。
这就是为什么它不适用于Oracle中的空列表。
回到你的问题:
如何适当地处理list-is-empty-case
您必须找到另一种方法,而不是获取ID并将其包含在NOT IN
子句中
由于您对查询没有任何控制权,因此您必须包含有关3方工具的详细信息,并希望有解决方法。
有关此内容的更多信息:
注意: (以防某些SQL Server用户发现此帖子)
如果您使用的是SQL Server,则查询将起作用,因为空字符串不会被处理为NULL
假设您已将SELECT * from TABLE1 where ID NOT IN (NULL)
设置为ANSI_NULLS
,即使第二个查询OFF
也可以。 Oracle中没有这样的设置。