2012-04-01 168 views
2

通常の機能を作成しました。それは正常に作成されました。私は解決方法「Oracleではクエリー内でDMLを実行できません」エラー

select reg('awlad','01968688680','545466455','12345') from dual 

でそれを実行すると、それは私に、このエラーを与える:

ORA-14551: cannot perform a DML operation inside a query 

は、どのように私はこの問題を解決することができますか?

CREATE OR REPLACE FUNCTION reg(
name in varchar2, 
cellNo in varchar2, 
voterId in varchar2, 
pass in varchar2 
) 
RETURN NUMBER 
IS 
succ NUMBER; 
BEGIN 
     succ:=0; 
     insert into logInfo values(loginfo_seq.nextval,cellNo,pass,0); 
     succ:=1; 
     insert into passInfo values(name,cellNo,voterId); 
     succ:=2; 
     RETURN succ; 
END; 

答えて

5

関数は、結果を計算して返しますが、データベースの状態は変更しません。 SELECTステートメントでデータベースの状態を変更できないため、関数内でDMLを(つまりテーブルに行を挿入する場合)SELECTステートメントで呼び出すことはできません。一般的に、ストアド・ファンクションではなくストアド・プロシージャとしてこの種のものを作成するほうがよいでしょう。

あなたがしたい、あなたが手続き

CREATE OR REPLACE PROCEDURE reg(name in varchar2, 
           cellNo in varchar2, 
           voterId in varchar2, 
           pass in varchar2, 
           succ out NUMBER) 
AS 
BEGIN 
    succ:=0; 
    insert into logInfo values(loginfo_seq.nextval,cellNo,pass,0); 
    insert into passInfo values(name,cellNo,voterId); 
    succ:=1; 
END; 

としてこれを作成したい場合は、ストアドプロシージャ

DECLARE 
    l_success_code NUMBER; 
BEGIN 
    l_success_code := reg('awlad','01968688680','545466455','12345'); 
END; 

を呼び出すのと同じようにPL/SQLブロックからこの関数を呼び出すことができますOUTパラメータを渡してプロシージャを呼び出す必要があります

DECLARE 
    l_success_code NUMBER; 
BEGIN 
    reg('awlad','01968688680','545466455','12345', l_success_code); 
END; 
+0

ありがとうございました。私はこれを試してみましたが、私はプロシージャを呼び出すとエラーが表示されます:間違った番号または 'REG'の呼び出しで引数の型。私の手順は次のとおりです。CREATE OR REPLACE PROCEDUREのREG(VARCHAR2で 名、VARCHAR2で cellNo、VARCHAR2で voterId、VARCHAR2で パス、 SUCCアウトNUMBER ) のsucc BEGIN AS:= 0; logInfoの値に挿入します(loginfo_seq.nextval、cellNo、pass、0)。 passInfoの値(name、cellNo、voterId)に挿入します。 succ:= 1; END; –

+0

@AwladLiton - 「OUT」パラメータを使用してプロシージャを作成した場合は、5番目のパラメータを渡す必要があります。それを行う方法を示すために私の答えを編集しました。 –

2

ログ情報がある場合は、autonomous transactionを使用して中間挿入を行うのが適切です。それは目的をデバッグするために有用であろうが、それはトランザクションではないので、(メイン・トランザクションがロールバックされた場合でも、挿入行が滞在するので)データを記録するために使用すべきではないことを

CREATE OR REPLACE FUNCTION reg(NAME IN VARCHAR2, 
           cellNo IN VARCHAR2, 
           voterId IN VARCHAR2, 
           pass IN VARCHAR2) 
    RETURN NUMBER IS 
    -- 
    PROCEDURE do_loginfo (p_id NUMBER, 
         p_cellNo VARCHAR2, 
         p_pass VARCHAR2, 
         p_x NUMBER) IS 
    PRAGMA AUTONOMOUS_TRANSACTION 
    BEGIN 
     INSERT INTO logInfo VALUES (p_id, p_cellNo, p_pass, p_x); 
     COMMIT; 
    END do_loginfo; 
    PROCEDURE do_passInfo (p_name VARCHAR2, 
          p_cellNo VARCHAR2, 
          p_voterId VARCHAR2) IS 
    PRAGMA AUTONOMOUS_TRANSACTION 
    BEGIN 
     INSERT INTO passInfo VALUES (p_name, p_cellNo, p_voterId); 
     COMMIT; 
    END do_passInfo; 
    -- 
    succ NUMBER; 
BEGIN 
    succ := 0; 
    do_logInfo (loginfo_seq.NEXTVAL, cellNo, pass, 0); 
    succ := 1; 
    do_passInfo (NAME, cellNo, voterId); 
    succ := 2; 
    RETURN succ; 
END; 

注意。

関連する問題