gpt4 book ai didi

sql - 设置变量时,记录的 IS NOT NULL 测试不返回 TRUE

转载 作者:行者123 更新时间:2023-11-29 11:39:44 25 4
gpt4 key购买 nike

如果记录存在,则使用 plpgsql 过程提取记录,如果存在,则对其进行处理。

变量是行类型:

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;

这些加注都没有出现在我的消息日志中——它只是从未进入区 block 。测试是否从 SELECT * INTO 接收到一行的正确方法是什么?

最佳答案

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

Neither of these raises appear in my messages log

未记录

首先,NOTICE 通常不会写入默认设置的数据库日志。 The manual:

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,也不是NOT NULL。因此,您的两个测试都失败了。

sqlfiddle with more details

相关:

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

解决方案:找到

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.

关于sql - 设置变量时,记录的 IS NOT NULL 测试不返回 TRUE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21765198/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com