elB*_*rde 2 postgresql plpgsql composite-types sql-null
我正在尝试创建一个函数,该函数应该将表行映射到我的用户定义类型(这是复合类型)并返回结果。如果该表中的某些列为 NULL,则IS NOT NULL检查我的自定义类型不起作用!
我有一个简单的复合类型:
CREATE TYPE my_custom_type AS (
sender VARCHAR(30),
destination VARCHAR(30),
count INTEGER
);
Run Code Online (Sandbox Code Playgroud)
还有一张桌子:
CREATE TABLE messages (
id INTEGER PRIMARY KEY,
sender VARCHAR(30),
destination VARCHAR(30),
count INTEGER
);
Run Code Online (Sandbox Code Playgroud)
在此示例中插入单行:
INSERT INTO messages VALUES (1, 'sender', 'destination', 100);
Run Code Online (Sandbox Code Playgroud)
现在我想创建一个函数,它将将该行作为自定义 Postgres 类型返回:
CREATE OR REPLACE FUNCTION my_custom_function()
RETURNS my_custom_type AS
$$
DECLARE
result my_custom_type;
BEGIN
SELECT sender, destination, count
FROM messages
LIMIT 1
INTO result;
IF result IS NULL THEN
RAISE EXCEPTION 'no data';
END IF;
RETURN result;
END; $$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
当我使用这个函数时,我得到了预期的结果:
SELECT * from my_custom_function();
Run Code Online (Sandbox Code Playgroud)
但是,当某些列更新为 NULL 时,就会开始出现意外行为:
UPDATE messages SET destination = NULL;
Run Code Online (Sandbox Code Playgroud)
但是如果我将IS NULL条件更改为IS NOT NULL条件:
CREATE OR REPLACE FUNCTION my_custom_function()
RETURNS my_custom_type AS
$$
DECLARE
result my_custom_type;
BEGIN
SELECT sender, destination, count
FROM messages
LIMIT 1
INTO result;
IF result IS NOT NULL THEN
RETURN result;
END IF;
RAISE EXCEPTION 'no data';
END; $$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
然后我得到一个错误: ERROR: no data
有人可以解释一下为什么这不起作用吗?对我来说完全是无稽之谈...
IS NULL如果所有元素都为 NULL,则为复合类型;IS NOT NULL如果所有元素都不为 NULL,则为复合类型。
这是 SQL 标准所要求的。
\n这会产生令人不快的后果,例如与复合类型x IS NOT NULL不同NOT x IS NULL。TRUE此外,测试返回的两个值IS NULL可以不同:
SELECT ROW(NULL, NULL) IS DISTINCT FROM NULL;\n\n ?column? \n\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\n t\n(1 row)\nRun Code Online (Sandbox Code Playgroud)\nSQL 标准显然在这方面做得并不好。从 pgsql-hackers 列表中阅读此线程,以进一步启发混淆。
| 归档时间: |
|
| 查看次数: |
896 次 |
| 最近记录: |