当我们开始将应用程序从使用Oracle迁移到PostgreSQL时,我们遇到了以下问题:
我们的许多Oracle脚本都会创建可在PostgreSQL中不存在的Oracle特定表上使用的触发器。在PG数据库上运行这些脚本时,它们不会引发错误。 仅当触发触发器时,才会引发错误。
示例代码:
-- Invalid query under PostgreSQL
select * from v$mystat;
-- Create a view with the invalid query does not work (as expected)
create or replace view Invalid_View as
select * from v$mystat;
-- Create a test table
create table aaa_test_table (test timestamp);
-- Create a trigger with the invalid query does(!) work (not as expected)
create or replace trigger Invalid_Trigger
before insert
on aaa_test_table
begin
select * from v$mystat;
end;
-- Insert fails if the trigger exists
insert into aaa_test_table (test) values(sysdate);
-- Select from the test table
select * from aaa_test_table
order by test desc;
是否可以通过更改行为来在触发器创建时引发错误?
亲切的问候, 锤子
编辑:
我意识到,我们实际上并不使用基本的PostgreSQL,而是使用EDB。 这可能可以解释为什么创建触发器的语法似乎错误。 抱歉造成我的困惑。
答案 0 :(得分:0)
除非您有configured Postgres在创建函数时推迟验证,否则它将触发错误。
在创建触发器之前尝试发出此消息:
set check_function_bodies = on;
创建触发器应显示
ERROR: syntax error at or near "trigger"
LINE 1: create or replace trigger Invalid_Trigger
答案 1 :(得分:0)
在Postgres中,触发器基于函数。 EDB语法隐藏了这一点,但实际上触发功能是自动创建的。
您可以正确创建一个引用不存在的表的函数,例如:
create or replace function select_from_non_existing_table()
returns bigint language plpgsql as $$
begin
select count(*)
from non_existing_table;
end $$;
如果该表不存在,则在执行该函数时会引发错误:
select select_from_non_existing_table();
ERROR: relation "non_existing_table" does not exist
LINE 2: from non_existing_table
^
QUERY: select count(*)
from non_existing_table
CONTEXT: PL/pgSQL function select_from_non_existing_table() line 3 at SQL statement
但是,您可以创建表,然后成功执行函数。
与创建视图时的情况完全不同。 create view ...
命令会立即执行,因此无法成功完成。
在Postgres中,在创建函数时无法进行这种语义检查。另请参见PostgreSQL vs Oracle: “compile-time” checking of PL/pgSQL