PL SQL TRIGGER / PROCEDURE

时间:2017-01-03 15:26:15

标签: oracle stored-procedures plsql

我在PL / SQL中使用Trigger和Procedure创建了一个表,当我在student1表中插入第10条记录时,触发器被触发并自动调用procedure和create table。当我运行我的查询时,我收到以下错误:

Connecting to the database Spring.

ORA-04092: cannot COMMIT in a trigger
ORA-06512: at "EXIMUSER.CREATE_TABLE", line 13
ORA-06512: at "EXIMUSER.NEW_TABLE", line 10
ORA-04088: error during execution of trigger 'EXIMUSER.NEW_TABLE'
ORA-06512: at line 3
12
test-trigger-procedure:
Process exited.
Disconnecting from the database Spring. 

触发

create or replace TRIGGER NEW_TABLE 
before INSERT ON student1
for each row
DECLARE v_rows NUMBER(10);
BEGIN
select count(*) into v_rows from student1;
DBMS_OUTPUT.PUT_LINE(v_rows);
IF v_rows < 10 then
        insert into kaiser(ID,NAME) values(:new.myid,:new.name);
        commit;
    --DBMS_OUTPUT.PUT_LINE('test123'); 
    else
         EXIMUSER.create_table(:new.myid,:new.name);
         commit;
        End if;
END; 

程序

create or replace PROCEDURE CREATE_TABLE (MYID IN NUMBER := NULL, 
inName IN VARCHAR2 := NULL ) 
AUTHID CURRENT_USER IS v_sql varchar2(200); 
table_found EXCEPTION; 
PRAGMA EXCEPTION_INIT(table_found, -955); 
BEGIN 
DBMS_OUTPUT.PUT_LINE('test-trigger-procedure:');
execute immediate 'create table fan3(id NUMBER(10),name varchar(20))';
--DBMS_OUTPUT.PUT_LINE('test123');
END CREATE_TABLE;

1 个答案:

答案 0 :(得分:1)

@mohamed,

请在下面找到经过纠正的代码供您参考。就像我的朋友说的那样,你不能在触发器内部使用commit,除非它是一个独立的事务(Pragma AUTONOMOUS_TRANSACTION)。在你的情况下根本没有必要。但是,既然你已经要求它,请找到下面的代码。

同时创建表格是一个非常糟糕的主意。如果行数超过10,请检查会发生什么?每次插入记录时(当记录数超过10时),Oracle都会尝试创建相同的表,并会引发异常。请避免在未来的程序中创建表格,因为这是一个非常糟糕的主意。

触发器:

create or replace TRIGGER NEW_TABLE 
before INSERT ON student1
for each row
DECLARE 
PRAGMA autonomous_transaction;
v_rows NUMBER(10);
BEGIN
select count(*) into v_rows from student1;
DBMS_OUTPUT.PUT_LINE(v_rows);
IF v_rows < 10 then
    insert into kaiser(ID,NAME) values(:new.myid,:new.name);
else
    create_table(:new.myid,:new.name); 
     End if;
END; 
/

步骤:

create or replace PROCEDURE CREATE_TABLE (MYID IN NUMBER := NULL,inName IN     VARCHAR2 := NULL ) 
AUTHID CURRENT_USER IS v_sql varchar2(200); 
c number;
table_found EXCEPTION; 
PRAGMA EXCEPTION_INIT(table_found, -955); 
BEGIN 
DBMS_OUTPUT.PUT_LINE('test-trigger-procedure:');
select count(1) into c from user_tables where table_name='FAN3';
if (c>0) then
dbms_output.put_line('Table already exists');
else
execute immediate 'create table fan3(id NUMBER(10),name varchar(20))';
END if;
END CREATE_TABLE;

请注意,上述代码不是100%有效,我也不会推荐它。但OP已经询问如何在一个由触发器调用的过程中创建一个表,因此我正在分享答案。