dia*_*hol 1 oracle triggers plsql ddl-trigger
我想用ddl触发器(在放置之前)创建一个备份表,并遇到以下问题.
发生第一次丢弃时没关系:a_backup表包含丢弃表的数据.但为什么我不能放弃另一张桌子?
ORA-01031:权限不足
create table b (x number);
Run Code Online (Sandbox Code Playgroud)
- 表B已创建.
create table a (x number);
Run Code Online (Sandbox Code Playgroud)
- 表A已创建.
create table a_backup as select * from a where 1 = 0;
Run Code Online (Sandbox Code Playgroud)
- 表A_BACKUP已创建.
create or replace trigger a_backup_tr
before drop
on database
begin
IF ora_dict_obj_name <> 'A' then
null;
ELSIF ora_dict_obj_name = 'A'
and ora_dict_obj_owner = 'TRANEE' then
insert into a_backup
select * from a;
ELSE null;
end if;
end;
/
Run Code Online (Sandbox Code Playgroud)
- 触发A_BACKUP_TR编译
-- 1
drop table a;
Run Code Online (Sandbox Code Playgroud)
- 表A下降.
-- 2
drop table b;
Run Code Online (Sandbox Code Playgroud)
- ORA-04045:重新编译/重新验证TRANEE.A_BACKUP_TR期间出错
- ORA-01031:权限不足
除了再次运行create或replace trigger脚本之外,您不能删除任何表.IF-THEN部分有问题吗?当表A不存在时,IF语句必须进入NULL状态?
但为什么我不能放弃另一张桌子?
insert into a_backup select * from a;
Run Code Online (Sandbox Code Playgroud)
在触发器中,您明确引用表A,此时它不存在.
您可以使用动态SQL:
create or replace trigger a_backup_tr
before drop
on database
begin
IF ora_dict_obj_name <> 'A' then
null;
ELSIF ora_dict_obj_name = 'A' and ora_dict_obj_owner = 'TRANEE' then
EXECUTE IMMEDIATE 'insert into tranee.a_backup select * from tranee.a';
ELSE null;
end if;
end;
/
Run Code Online (Sandbox Code Playgroud)
就个人而言,我不喜欢使用触发器来实现这种机制.盲目插入也SELECT *可能会失败,如果将来架构漂移.也许更好的方法是Flashback Drop(回收站)
编辑:
正如@wolφi所提到的那样,你可以在触发器中创建表:
create or replace trigger a_backup_tr
before drop
on database
begin
IF ora_dict_obj_name <> 'A' then
null;
ELSIF ora_dict_obj_name = 'A' and ora_dict_obj_owner = 'TRANEE' then
--TODO: additional check if table already exists
EXECUTE IMMEDIATE 'CREATE TABLE tranee.a_backup AS SELECT * FROM tranee.a';
ELSE null;
end if;
end;
/
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
366 次 |
| 最近记录: |