Sybase ASE 中null is null的处理结果是什么?
Sybase ASE对null is null的处理结果是什么呢?
下面的SQL语句会返回所有的对象名吗?
select name from sysobjects where type=null or null is null
答案是:根据ASE版本不同,结果也不同。
在ASE v15.0.3之前的版本中会报下面的错误:
Invalid operator for datatype op: is null type: VOID TYPE.
在v15.0.3及以后的版本中,对is null的处理结果和我们平时直观的想法相同,
上面SQL语句会返回所有的对象名称。
原因在于ASE判断是否为空时的处理方式。ASE处理 值 is null 这个表达式时,
会先将null值转化成欲比较的值所对应的数据类型;因此,在处理 NULL is null时,
会先将null值转化成欲比较的值(NULL)所对应的数据类型,而值(NULL)对应的数据
类型是未知的。于是,报错:VOID TYPE。
在v15.0.3及更高版本中,解决了报错的问题,能够按照我们平时的习惯正常处理null is null
但是,请慎用null is null这种用法。比较经典的一个应用为,在java程序中有如下SQL语句:
select id from sysobjects where name=? or ? is null
如果该SQL接收到传入的非空对象名称,那么会返回其对应的对象ID。 如果该SQL没有接收到参数,
也就是传入空的对象名称,则返回所有的对象ID。
为了适用ASE多个版本,请将以上SQL修改为:
select id from sysobjects where name=? or isnull(?,'') = ''
-----------------------------------------------------------
ASE中 is null与=null是相等的吗?
答案是肯定的。
ASE中判断一个表达式是否为空,使用is null 或者 = null都是可以的。
但是,在SQL Standard中,is null与 =null的处理结果是不同的。
SQL标准中,判断一个表达式是否为空,需要使用is null。 null也就是空,所代表的值是未知的,
那么用未知的值(NULL)与未知的值(NULL)进行比较,结果怎么会可知呢?
然后,ASE默认情况下会给你一个可知的结果。 就是: is null 相当于 =null
在ASE中将ansinull选项打开,则处理方式与SQL标准相同了。
请看下面的例子:
默认情况下ansinull是关闭的,
1> select * from t
2> go
id name
----------- ------------------------------
1 NULL
(1 row affected)
1> select @@options
2> go
--------------------------
0x80210000000f034403001000
(1 row affected)
1> select * from t where name is null
2> go
id name
----------- ------------------------------
1 NULL
(1 row affected)
1> select * from t where name=null
2> go
id name
----------- ------------------------------
1 NULL
(1 row affected)
将选项ansinull打开后,
1> set ansinull on
2> go
1> select @@options
2> go
--------------------------
0x80210000020f034403001000
(1 row affected)
1> select * from t where name is null
2> go
id name
----------- ------------------------------
1 NULL
(1 row affected)
1> select * from t where name=null
2> go
id name
----------- ------------------------------
(0 rows affected)
注意比较全局环境变量
0x80210000000f034403001000 和
0x80210000020f034403001000
是设置ansinull前后的会话选项值。
参考文章:
NULLs in Sybase ASE : http://sybasease.blogspot.com/2005/05/nulls-in-sybase-ase.html
ASE 12.5.2 - Invalid operator for datatype op: is null type: VOID TYPE
总结:
null is null在ASE v15.0.3前的版本中是不能使用的,在ASE v15.0.3以后续版本可以使用。
null = null在ASE v15.0.3之前的版本中不能使用,在ASE v15.0.3 ESD#1 和 ASE v15.0.3 ESD#2上面可以使用,但是在ASE v15.0.3 ESD#4还有ASE v15.7上面不能使用。
以上是我亲自测试的结果。 不对之处,欢迎指正!