在PostgreSQL中引发错误

22
CREATE OR REPLACE FUNCTION msgfailerror() RETURNS trigger AS 
' BEGIN 
    IF NEW.noces< new.first_column THEN 
        RAISE EXCEPTION 'cannot have a negative salary'; 
    END IF; 
   return new; 
END' LANGUAGE plpgsql

触发器

create trigger msgfail before insert on first for each row 
execute procedure msgfailerror()

出现错误:

  

语法错误:“cannot”附近的行 5: RAISE EXCEPTION 'cannot have a negative ...

我几乎为每个字段设置了一个验证。 我想在插入时触发器检查所有验证,并在全部完成后引发一次错误日志。 我应该在raise notice上使用raise exception吗?

例如:

Insert into first (first_column, noces,dob) values ('4545','75','545') 

我正在检查 noces 是否小于 first_column,对于同一行,我想检查 dob 是否大于80,如果 first_column 是整数并且针对所有验证引发错误。提前致谢。


2
你正在进行数字比较,但在INSERT语句中却使用字符字面量。如果nocesfirst_column是字符列,那么<将不会按照你的期望工作。永远不要在字符列中存储数字! - user330315
3个回答

42

引号使用不正确。更简单的方式是使用 美元符号引用 $$

CREATE OR REPLACE FUNCTION msgfailerror() 
RETURNS trigger AS 
$$
BEGIN 
  IF NEW.noces< new.first_column THEN 
    RAISE EXCEPTION 'cannot have a negative salary'; 
  END IF; 
  return new; 
END;
$$
LANGUAGE plpgsql;

但另一方面,使用检查约束有什么问题吗?


使用上述代码时,它没有显示任何错误...但也没有引发任何异常,只是插入值...并且将检查约束是否显示任何错误?我不想中止操作,我只想抛出一条消息,例如您输入的值未通过这些约束。 - user1686308
3
对于检查约束条件再加上一个+1。 - user330315
如果你抛出一个异常 - 就像你在问题中所做的那样 - 除非你捕获到该异常,否则你总是会回滚(中止)事务。违反 CHECK 约束也会产生同样的结果。在这种情况下,你需要发出一个 警告通知 - Erwin Brandstetter
@user1686308:请参考此SQLFiddle示例:http://sqlfiddle.com/#!1/82c39/1 - user330315
谢谢,我会尽可能使用检查约束,因为我需要处理大约180个验证。祝我好运。感谢大家的帮助。 - user1686308

5

你没有任何问题,唯一的问题是使用了引号

请更改为:

RAISE EXCEPTION 'cannot have a negative salary';

to:

RAISE EXCEPTION ''cannot have a negative salary'';

"

''" 与 "

" 不同。
"

''

" 表示两个单引号。

欢迎来到 Stack Overflow!请不要在您的帖子下留下电子邮件地址;联系方式应该放在您的个人资料中。 - Glorfindel

1

我同意Frank的观点,你可以更好地使用约束,但你称其为验证。验证通常在插入之前进行。如果您想要验证插入操作,可以使用函数而不是触发器或约束。

当您编写函数时,答案是引发异常或通知,只要没有写入操作,通知就足够了(同时离开函数)。一旦对数据库进行了写入,您必须使用异常,因为它们执行回滚。

像这样:

CREATE OR REPLACE FUNCTION field_validate(p_int int) RETURNS boolean AS $$

DECLARE
 i_id int;
BEGIN 
  if p_int > 10 then
   raise notice 'should be smaller then 10';
   return false;
  end if;
  insert into tbl_numbers(firstfield) values(p_int) returning id in i_id;
  insert into tbl_fake(nofield) values(i_id);
  return true;
EXCEPTION
  WHEN raise exception THEN
   return false;
END;
$$ LANGUAGE plpgsql;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接