【发布时间】:2015-02-05 15:36:31
【问题描述】:
我有一个函数registration(),它应该在某些情况下向表中添加一行。我已经包含了一个 sn-p 代码和一个调用的输出。
如果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;
【问题讨论】:
-
"我想引发异常而不是添加行" --- 并发调用呢?如果 2 个调用同时通过了这个检查怎么办?
-
你能编辑你的帖子并显示Email的整个功能和表格结构吗?根据目前的信息,无法说出问题所在。一种可能的原因:rowt 是 RECORD 类型的变量,IS NOT NULL 应该对记录字段进行操作。
-
参见"Executing a Query with a Single-row Result",以及特殊的
FOUND变量。 -
@zerkms:
SET ISOLATION LEVEL SERIALIZABLE是一个不错的安全默认值,您可以随时根据具体情况将其关闭。 -
@Kevin:注意:
SET ISOLATION LEVEL SERIALIZABLE会对数据库负载产生负面影响。它显着增加了锁的数量。
标签: postgresql null row plpgsql