2012-04-01 62 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

函數應該計算並返回一個結果,而不是改變數據庫的狀態。如果要在函數中執行DML(即,如果要將行插入表中),則不能在SELECT語句中調用該函數,因爲SELECT語句不能更改數據庫的狀態。一般來說,你最好把這種事情做成存儲過程而不是存儲功能。

你可以調用從PL/SQL塊這個功能就像您將調用存儲過程

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

如果你想創建這個作爲一個過程

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; 

,那麼你會需要通過傳入OUT參數

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

謝謝洞穴。我試過這個,但是當我調用過程時,它向我顯示錯誤:調用'REG'時錯誤的數字或參數類型。我的程序是:CREATE OR REPLACE PROCEDURE REG(在VARCHAR2 名, cellNo在VARCHAR2, voterId在VARCHAR2, 通在VARCHAR2, SUCC出NUMBER ) AS BEGIN SUCC:= 0; 插入logInfo值(loginfo_seq.nextval,cellNo,pass,0); 插入到passInfo值(name,cellNo,voterId); succ:= 1; END; – 2012-04-01 17:24:35

+0

@AwladLiton - 如果使用'OUT'參數創建過程,則需要傳入第五個參數。編輯我的答案,展示如何做到這一點。 – 2012-04-01 17:31:44

2

如果所有你wan要做的事情是記錄信息,那麼使用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; 

注意,這將是用於調試的目的是有用的,但因爲它不是事務性的,它不應該被用來記錄數據(因爲插入的行會留即使主事務回滾)。

相關問題