2017-01-03 8 views
0

私はPL/SQLでトリガとプロシージャを使用してテーブルを作成しました。これは、student1テーブルに10番目のレコードを挿入するときにトリガが起動され、プロシージャを呼び出してテーブルを自動的に作成するときに作成されました。私は私のクエリを実行すると、私は次のエラーを取得:@mohamedPL SQL TRIGGER/PROCEDURE

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; 
+3

エラーメッセージについて何が混乱していますか?あなたのトリガーには 'commit'があります。それは許されない。あなたの手続きは、暗黙のうちにコミットするDDL(動的)を行っています。そうすることも許されません。 –

+0

ありがとう、他の可能な方法でテーブルを作成する場合 – Mohamed

+0

[あなたはそれを行うことができます](http://stackoverflow.com/a/20518281/266304)、本当にすべきではありません。その答えはデータベースリンクを作成することですが、DDLには同じ問題があります。そこから他のアプローチへのリンクがあります。しかし、これは良いアイデアではなく、実験中でもありません。その場でデータベースオブジェクトを作成することは何か間違っていることを意味します。スキーマは実際には静的でなければなりません。また、次のレコードを挿入するとどうなりますか?テーブルを再度作成しようとします - それは既に存在します。これは現実世界でやりたいことではありません。 –

答えて

1

をご参考のため、以下の整流コードを見つけてください。 。私の友人のように、独立トランザクション(Pragma AUTONOMOUS_TRANSACTION)でない限り、トリガーの内部でコミットを使用することはできません。あなたの場合は全く必要ではありません。しかし、あなたがそれを求めてきたので、以下のコードを見つけてください。

また、テーブルを作成することは非常に悪い考えです。行数が10を超えるとどうなるか確認してください。 Oracleは、レコードが挿入されるたびに(レコード数が10を超えると)同じ表を作成しようとしますが、例外が発生します。非常に悪い考えであるので、手続きの中でテーブルを作成することは避けてください。

トリガー:

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; 

Guysは上記のコードは100%効率的ではないとも私はそれをお勧めしますのでご了承ください。しかし、OPは、トリガーによって呼び出されるプロシージャ内にテーブルを作成する方法を尋ねました。したがって、私は答えを共有しています。

+0

:申し訳ありませんが動作しない...私はDDL文(テーブルを作成する)をサポートしていないトリガをreliazed ...他の方法plsが私を助ける場合は、10行目のテーブルを動的に作成挿入する場合。 – Mohamed

+0

他のコードを試しましたか?そのうまく動作します。私はそれを変更しました。テーブルの作成も機能しています。私はプラグマ自律ブロックをトリガのために使用しました。 –

+0

@モハメド私はコードを更新しました。あなたのすべてのニーズは満足できません。ありがとうございました。 –