gpt4 book ai didi

postgresql - 为什么在检查行类型时 IS NOT NULL 为 false?

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

我有一个函数 registration(),它应该在某些情况下向表中添加一行。我包含了一段代码和一次调用的输出。

如果 select * 返回一个非空表行(它根据 RAISE NOTICE 执行),我想引发异常而不添加该行。该示例似乎表明 rowt 不为空,但 rowt IS NOT NULL 返回 f(并且未引发异常)。

我希望这是我没有看到的小事。

select * into rowt from Email where email_email = eml;
RAISE NOTICE '%, rowt IS NOT NULL:%',rowt, rowt IS NOT NULL;
if rowt IS NOT NULL THEN
RAISE EXCEPTION 'email address, %, already registered.' , eml;
END IF;

输出:

NOTICE:  (7,,,), rowt IS NOT NULL:f

registration
--------------
21
(1 row)

CREATE TABLE IF NOT EXISTS Email (
email_email VARCHAR(50) NOT NULL,
email_password VARCHAR(50) NOT NULL,
email_id integer DEFAULT nextval('email_email_id_seq'::regclass) NOT NULL,
email_person_id integer
);
CREATE OR REPLACE FUNCTION registration( wr text ) RETURNS integer AS $rL$
DECLARE
eml text;
pwd text;
nm text;
rle text;
emid integer;
rowt Email%ROWTYPE;
BEGIN
eml := getWebVarValue( wr , 'email' );
select * into rowt from Email where email_email = eml;
RAISE NOTICE '%, rowt IS NOT NULL:%', rowt, rowt IS NOT NULL;
IF rowt IS NOT NULL THEN
RAISE EXCEPTION 'email address, %, already registered.' , eml;
END IF;
pwd := getWebVarValue( wr , 'password' );
IF pwd IS NULL THEN
RAISE EXCEPTION 'No password specified in registration.';
END IF;
INSERT INTO Email VALUES (eml,pwd) RETURNING Email.email_id INTO emid;
--nm = getWebVarValue( wr , 'name' );
--rle = getWebVarValue( wr , 'role' );
RETURN emid;
END;
$rL$ LANGUAGE plpgsql;

最佳答案

<row-type> IS NOT NULL

作为@Pavel provided , 检查 <row-type> IS NOT NULL不像你预期的那样工作。它返回 TRUE当且仅当每一列NOT NULL .

可以反转您的测试表达式:

IF <b>rowt IS NULL</b> THEN
-- do nothing
ELSE
RAISE EXCEPTION 'email address, %, already registered.' , eml;
END IF;

您找到的任何行都至少包含一列 NOT NULL ,因此 rowt IS NULL只返回 TRUE如果没有找到。

参见:

不过,为允许全 NULL 行的表留下一个极端情况。

更好的解决方案

测试特殊变量 FOUND 相反(如 @Mike commented ):

PERFORM FROM email WHERE email_email = eml;

IF FOUND THEN
RAISE EXCEPTION 'email, %, already registered.', eml;
END IF;

因为我们实际上对返回的行不感兴趣,所以替换 SELECTPERFORM丢弃结果。要么设置特殊变量 FOUND相应地。
SELECT列表(或 PERFORM 列表,真的)可以是空的,因为只有一行的存在很重要。

更简单,但使用 EXISTS :

IF EXISTS (SELECT FROM email WHERE email_email = eml) THEN
RAISE EXCEPTION 'email, %, already registered.', eml;
END IF;

参见:

关于postgresql - 为什么在检查行类型时 IS NOT NULL 为 false?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27350232/

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