sql – 对于记录的IS NOT NULL测试在设置变量时不返回TRUE

前端之家收集整理的这篇文章主要介绍了sql – 对于记录的IS NOT NULL测试在设置变量时不返回TRUE前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
使用plpgsql过程提取记录(如果存在),如果存在,则使用它执行某些操作.

变量是一个rowtype:

my_var my_table%rowtype;

我用sql语句填充它:

select * from my_table where owner_id = 6 into my_var;

我知道它肯定有一行:

raise notice 'my_var is %',my_var;

返回:

NOTICE:  my_var is (383,6,10)

但是现在我想测试一下,如果条件失败,它会得到记录和两者:

if my_var is null then
  raise notice 'IT IS NULL';
end if;
if my_var is not null then
  raise notice 'IT IS NOT NULL';
end if;

这些加注都没有出现在我的消息日志中 – 它只是从不进入块.如果从SELECT * INTO收到一行,测试的正确方法是什么?

解决方法

我看到两个可能的原因,为什么……

Neither of these raises appear in my messages log

没有记录

首先,通常不会使用默认设置将NOTICE写入数据库日志.我引用the manual here

log_min_messages (enum)

Controls which message levels are written to the server log. Valid values are DEBUG5,DEBUG4,DEBUG3,DEBUG2,DEBUG1,INFO,NOTICE,WARNING,ERROR,LOG,FATAL,and PANIC. (…)
The default is WARNING. Note that LOG has a different rank here than in client_min_messages.

大胆强调我的.另请注意client_min_messages的不同默认值(NOTICE)(手册中的上一项).

测试无效

其次,考虑如何计算行表达式.如果(并且仅当)每个元素都为NULL,则测试row_variable IS NULL返回TRUE.给出以下示例:

SELECT (1,NULL) IS NULL AS a     -- FALSE,(1,NULL) IS NOT NULL AS b -- also FALSE

两个表达式都返回FALSE.换句话说,行(或记录)变量(1,NULL)既不是NULL,也不是NULL.因此,两个测试都失败了.

– > SQLfiddle with more details.

在此相关答案的CHECK约束中,此行为的更多详细信息,说明,链接和可能的应用程序:
NOT NULL constraint over a set of columns

您甚至可以使用NULL(rec:= NULL)分配记录变量,这会导致每个元素都为NULL – 如果类型是众所周知的行类型.否则,我们正在处理匿名记录,结构未定义,您无法访问元素.但是在你的例子中(例如总是众所周知的)类型的情况并非如此.

解决方案:找到了

What’s the correct way to test if you received a row from a SELECT * INTO?

您必须考虑该行可能为NULL,即使它已被分配.查询很可能返回了一堆NULL值(如果查询中的表定义允许NULL值).这种测试在设计上是不可靠的.

有一种简单而安全的方法.使用GET DIAGNOSTICS …或(如适用)特殊变量FOUND:

SELECT * FROM my_table WHERE owner_id = 6 INTO my_var;

IF NOT FOUND THEN
   RAISE NOTICE 'Query did not return a row!';
END IF;

Details in the manual.

猜你在找的MsSQL相关文章