变量是一个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
,andPANIC
. (…)
The default is WARNING. Note thatLOG
has a different rank here than inclient_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;