我需要将一些Oracle PL / SQL代码移植到Postgres。这是我第一次与Postgres合作。
在Oracle中,关于异常,我可以这样:
IF v_customer_id IS NULL OR v_email IS NULL THEN RAISE invalid_paramters; END IF;
在Postgres中如何完成?基本上验证输入,如果验证失败,则调用自定义处理程序以执行任何操作。据我了解,Postgres不支持自定义命名异常。
感谢您的时间。
答案 0 :(得分:3)
您可以将RAISE
与自定义消息和特定的sqlstate常量一起使用:
--Anonymous block for testing purposes
DO $$
BEGIN
RAISE invalid_parameter_value USING MESSAGE = 'Invalid customer or email';
END $$;
或者您可以简单地引发一个通用异常:
DO $$
BEGIN
RAISE EXCEPTION 'A generic exception (P0001)';
END $$;
您还可以处理异常:
DO $$
BEGIN
--This will raise a division by zero
PERFORM 0 / 0;
--You can catch a exception with a EXCEPTION block
EXCEPTION
WHEN division_by_zero THEN
RAISE INFO 'Division by zero catched';
WHEN raise_exception THEN
RAISE INFO 'Another error catched...';
END $$;
并获取有关异常的更多详细信息:
DO $$
DECLARE
error_msg text;
BEGIN
--This will raise a division by zero
PERFORM 0 / 0;
--You can get more about error with GET STACKED DIAGNOSTICS
EXCEPTION
--Tip: OTHERS keyword will catch any exception
WHEN OTHERS THEN
GET STACKED DIAGNOSTICS error_msg = MESSAGE_TEXT;
RAISE EXCEPTION 'My custom exception: %', error_msg;
END $$;
我建议您看一下sqlstates和control structures,以获取有关PostgreSQL中错误处理的更多信息。
答案 1 :(得分:0)
do $$
declare
v int := 1;
begin
begin
if v < 2 then -- Validation here
raise sqlstate 'A0001'; -- custom SQL state, any five upper case letters and/or digits
end if;
exception -- Catch exception in the nested BEGIN ... END block
when sqlstate 'A0001' then
raise notice 'Here is my exception handler';
v := 2;
end;
raise notice 'Continue here with value %', v; -- Reports that the v = 2
end $$;
答案 2 :(得分:0)
您可以在begin...end
部分的位置添加一个嵌套的RAISE EXCEPTION
块,而不是在主异常块中捕获它,并在其中引发异常,然后在嵌套的其他异常块中捕获它使用RETURN
关键字进行屏蔽。希望对您有所帮助。
do
$$
begin
raise notice 'line 1';
begin
raise exception 'raising exception';
exception
when others then
raise notice 'captured in nested block';
end;
return;
raise notice 'check if it continues';
exception
when others then
raise notice 'main block others';
end;
$$
language plpgsql;