在PostgreSQL和Oracle中,何时将NULL和空字符串视为相同?

时间:2018-09-29 01:51:04

标签: sql oracle postgresql

我创建了以下dbfiddle,您可以在其中看到 field <>''排除 field 为null的情况。

https://www.db-fiddle.com/f/xdfayYMvdRZDRRASvGFdpT/0

CREATE TABLE test (
  prd_typ_cd bpchar,
  prd_prnt_typ_cd bpchar,
  prd_chld_typ_cd bpchar
);
INSERT INTO test VALUES ('SHC', null, 'DIV');

INSERT INTO test VALUES ('DIV', 'SHC', 'DEP');

INSERT INTO test VALUES ('DEP', 'DIV', null);

SELECT * FROM test WHERE prd_chld_typ_cd <> '';

我很惊讶地看到这一点,因为在大多数语言中,NULL和''(空字符串)被区别对待。

上面的示例来自PostgreSQL数据库。在Oracle数据库上是否也是如此?在什么情况下PostgreSQL和Oracle会将NULL和''(空字符串)视为同一东西?

2 个答案:

答案 0 :(得分:4)

NULL '' 在Postgres中被区别对待。

 prd_chld_typ_cd <> ''
NULLprd_chld_typ_cd时,

返回NULL。这是大多数涉及NULL的操作的典型行为。您会发现:

 prd_chld_typ_cd = ''

当该列为NULL时,其行为完全相同。

对于任何其他值,表达式返回true或false。如果返回值,您将很容易看到这一点:

SELECT t.*, prd_chld_typ_cd <> ''
FROM test t;

正在发生的事情是,NULL和false在WHERE过滤器中的处理方式相同-都过滤出该行。

相比之下,NULL''是Oracle中的同义词。但事实证明

 prd_chld_typ_cd <> ''
 prd_chld_typ_cd = ''

prd_chld_typ_cdNULL时,两者的行为相同。但是,可惜的是,在Oracle中,两个总是都返回NULL,因为''等效于NULL

答案 1 :(得分:0)

我不了解postgres,但是oracle对于空字符串有一些古怪之处,如果您打算在应用程序中支持它,则需要注意以下几点: 1.在Oracle中,空字符串始终被视为NULL:如果插入空字符串,则将读回NULL。在oracle中,空字符串根本不存在:在处理varchar值时,如果可以写''而不是NULL,则它只是一个“语言语法糖”。 2.在Oracle中       '' 一片空白  将评估为TRUE。空字符串是DE FACTO null 3.在oracle中,任何涉及NULL值的比较都将始终评估为FALSE。这意味着您可以应用于NULL值并且可以返回TRUE的唯一运算符是“ is null”和“ is not null”

上面的结果是,在oracle中,无论myvar的实际值如何,以下所有表达式都将计算为FALSE:

 myvar = '' 
 myvar <> '' 
 myvar = null
 myvar <>null

即使这些计算结果始终为假

 null = null
 null<>null
 null = '' 
 null <> '' 

因此以下更新不会更新任何内容:

更新mytab设置myfield ='X',其中myfield =''

正如我所说,您只能使用'is null'和'is not null'运算符。  所以你必须写成

更新mytab设置myfield ='X',其中myfield为null。

P。 S.将null作为不同的可比较值的唯一Oracle函数是Decode()。可能这是一个错误,但今天有太多的软件依靠此行为来修复它。

  decode( <expression>,
          <caseval 1>,  < exitval 1>,
          <caseval 2>,  < exitval 2>,
          .... 
           <elseval>) 

是sql构造案例的旧实现...在此函数中,oracle将NULL(因此也包括空字符串)视为可比较值。因此您可以将NULL用于,它将匹配空值(和空字符串)。这是唯一发生这种情况的情况。

如果您尝试使用标准的SQL Case构造进行操作,它将无法正常工作:oracle没有在此处复制错误。

P。 S:很抱歉,如果回复的格式看起来很奇怪。我正在用手机写...