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

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

  •  0
  • ktm5124  · 技术社区  · 6 年前

    我创建了下面的dbfiddle,在其中可以看到 菲尔德<>“ 排除了以下情况: 领域 是空的。

    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 回复  |  直到 6 年前
        1
  •  5
  •   Gordon Linoff    6 年前

    NULL '' 在研究生中受到不同的对待。

     prd_chld_typ_cd <> ''
    

    返回 无效的 什么时候 prd_chld_typ_cd 无效的 .这是大多数涉及 无效的 .你会发现:

     prd_chld_typ_cd = ''
    

    当该列为 无效的 .

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

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

    发生的事情是 无效的 和false的处理方式相同 WHERE 过滤——两个都过滤掉行。

    相比之下 无效的 '' 是甲骨文中的同义词。但事实证明

     prd_chld_typ_cd <> ''
     prd_chld_typ_cd = ''
    

    两人的行为都是一样的 珠江三角洲中国典型cd 无效的 可惜,在甲骨文中,两者 总是 回来 无效的 --因为 '' 相当于 无效的 .

        2
  •  0
  •   Carlo Sirna    6 年前

    我不知道postgres的情况,但如果您计划在应用程序中支持空字符串,oracle有一些需要注意的问题: 1.在Oracle中,空字符串始终被视为NULL:如果插入空字符串,将读回NULL。在oracle中,空字符串根本不存在:如果在处理varchar值时可以写“”而不是NULL,那么它只是一个“语言语法糖”。 2.在甲骨文中 “”为空 将评估为真。空字符串实际上是空的 3.在oracle中,任何涉及空值的比较都将计算为FALSE。这意味着可以应用于NULL值并返回TRUE的运算符只有“is NULL”和“is not NULL”

    上述操作的结果是,在oracle中,无论myvar的实际值是多少,以下所有表达式的计算结果都将为FALSE:

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

    即使这些评估也总是错误的

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

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

    更新mytab set myfield='X',其中myfield='X'

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

    更新mytab set myfield='X',其中myfield为空。

    另外,唯一一个将null视为不同可比值的oracle函数是Decode()。也许这是一个缺陷,但今天有太多的软件依赖于这种行为来修复它。

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

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

    如果你试图用标准的SQL用例构造来实现它,它是行不通的:oracle没有在那里复制这个bug。

    附言:如果回复的格式看起来很奇怪,那就很抱歉了。我在用手机写东西。。。