作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个函数 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;
因为我们实际上对返回的行不感兴趣,所以替换 SELECT
与 PERFORM
丢弃结果。要么设置特殊变量 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/
我是一名优秀的程序员,十分优秀!