[postgresql]世纪大坑之is null 以及 is not null一定是互斥的吗?

案例再现

某日,写一份关于判断是不是已经报名过的存储过程, 代码如下:

--变量定义区,定义一个row type等下暂时存储数据
  declare rowType_order_signed_up "pt_order"%rowType;
  declare enum_orderStatus "PartyOrderStatusEnumObj";
--这是存储过程正文
  --思路:获取符合条件的订单记录到rowType_order_signed_up然后判断是否有这条记录,如果有的话就表示用户已经报名了.提示报名,没有的话就可以报名


  --查看一下报名数据,自己是不是已经报名了。
     
  select * into rowType_order_signed_up from pt_order
  where "partyId" = rv_partyId and "userId" = rv_visitUserId

    and "payStatus" = 1
    and status = ANY(ARRAY[
      "getCodeFromEnumItem"(enum_orderStatus."hasJoined")
      ,
      "getCodeFromEnumItem"(enum_orderStatus."Wait4Audit")
      ,"getCodeFromEnumItem"(enum_orderStatus."Finish")
      ,"getCodeFromEnumItem"(enum_orderStatus."Expired")
      ])
    ;


  if rowType_order_signed_up is not null then

    raise notice '看到这里就可以明白,系统没有将rowType 判断为null';
  end if;

  if rowType_order_signed_up is  null then

    --报名过的。
    if rowType_order_signed_up.status="getCodeFromEnumItem"(enum_orderStatus."Wait4Audit") then
      op_result:="webTools_opResult"(false,0,
        '亲~您已经报名过该活动,系统已经通知活动发起人及时审核通过您的报名申请,请耐心等候。'
        );
      return;
    end if;

    if rowType_order_signed_up.status="getCodeFromEnumItem"(enum_orderStatus."hasJoined") then
      op_result:="webTools_opResult"(false,0,'亲~您已经成功报名了,请不要重复报名。');
      return;
    end if;

    if rowType_order_signed_up.status="getCodeFromEnumItem"(enum_orderStatus."Finish") then
      op_result:="webTools_opResult"(false,0,'亲~您已经完成活动了,不能再次报名哦。');
      return;
    end if;
    op_result:="webTools_opResult"(false,0,'亲~您已经报名了,请勿重复报名');
    return;
    end if;

然后发现,在实际运行过程中,无论如何执行,rowType的is not null判断返回的都是false,在数据表一看,
在这里插入图片描述

这个小老弟都已经没了十张票了,真有趣.

然后一查文档…
坑爹啊

官方说明

提示: 有些应用可能要求表达式expression = NULL 在expression为 NULL 时候返回真。 我们强烈建议这样的应用修改成遵循 SQL 标准。但是,如果这样修改是不可能的, 那么我们可以打开transform_null_equals配置参数, 让PostgreSQL将x = NULL 自动转换成x IS NULL。

注意: 如果expression是行值, 那么当行表达式本身为 NULL 或该行的所有字段都为 NULL 时,IS NULL将为真; 当行表达式本身不为 NULL 并且该行的所有字段都不为 NULL 时,IS NOT NULL 也将为真。因为这个行为,IS NULL和IS NOT NULL 并不总是为行值表达式返回相反的值,也就是, 一个同时包含NULL和non-null值的行值表达式将在两种情况下都返回false。 这个规定符合 SQL 标准,但是与PostgreSQL之前的版本不兼容。

is null 与is not null

解读

就是说,对于rowType这种数据行类型,只有不存在记录或者记录的所有字段都是null时候 is null 才=true,
而is not null的判断是–存在记录且记录里面所有字段都不能是null…

所以上面的判断就让一些小老弟可以不停买票了…身为作者就当不知道算了,票也不要退…

解决方案

用 if [not] exists 来判断有没有记录会方便一点,或者说,不想再一次表的情况下,想要用rowType判断的,那么就直接用:

  if rowType_order_signed_up."userId" is not null then

直接用rowType里面的某个肯定不是null的字段来判断

### 回答1: 在 PostgreSQL 中,可以使用 is null 来检查一个值是否为 NULL。例如,以下查询将返回表中列名为 column_name 的所有行,其中该列的值为 NULL: ``` SELECT * FROM table_name WHERE column_name IS NULL; ``` 相反,如果您想查找一个值不是 NULL 的行,可以使用 is not null。例如,以下查询将返回表中列名为 column_name 的所有行,其中该列的值不是 NULL: ``` SELECT * FROM table_name WHERE column_name IS NOT NULL; ``` ### 回答2: postgresql的isnull函数用于判断一个给定的表达式是否为null。如果是null,函数返回true,否则返回false。 在postgresql中,null代表一个缺失的或未定义的值。当一个字段没有被设置具体的值时,它被认为是null。 isnull函数可以用在select语句中,也可以用在where语句中。在select语句中,我们可以使用isnull函数来判断一个字段是否为null,以便进行相应的处理。例如,我们可以使用如下语句: SELECT column1, isnull(column2, 'N/A') AS column2 FROM table1; 这个例子中,isnull函数判断column2字段是否为null。如果是null,它将返回'N/A'作为column2的值,否则返回column2的实际值。 在where语句中,我们可以使用isnull函数来过滤出不为null的记录。例如,我们可以使用如下语句: SELECT column1, column2 FROM table1 WHERE isnull(column2) = false; 这个例子中,isnull函数判断column2字段是否为null。如果不是null,则返回false,我们只选择返回值为false的记录。 总结而言,postgresql的isnull函数是用来判断一个表达式是否为null的。它在查询语句中能够提供对null值的处理和过滤的功能。 ### 回答3: "postgresql isnull" 是 PostgreSQL 数据库中的一个函数,用于判断一个字段的值是否为空。它的语法格式为: isnull(column_name, value_if_null) 其中,column_name 是要判断的字段名,value_if_null 是当字段为空时返回的值。 这个函数的作用是在查询数据时进行条件判断,可以根据字段是否为空来决定返回的结果。例如,我们可以使用 isnull 函数来查找所有年龄为空的用户: SELECT * FROM users WHERE isnull(age, true); 这个查询语句会返回所有年龄为空的用户记录。 另外,isnull 函数还可以在更新数据时使用。例如,我们可以使用 isnull 函数将年龄为空的用户的年龄设置为默认值 18: UPDATE users SET age = isnull(age, 18) WHERE id = 1; 这个更新语句会将 id 为 1 的用户年龄字段为空的记录的年龄设置为 18。 总之,"postgresql isnull" 是 PostgreSQL 数据库中的一个用于判断字段是否为空的函数,可以在查询和更新数据时使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值