2012-01-04 116 views
19

我正在使用數據分析工具,我的要求是接受來自用戶的值,將其作爲參數傳遞並將其存儲在表中。相當簡單明瞭,所以我坐在使用下面的語句「不能在查詢中執行DML操作」的解決方案?

begin 
complex('SomeValue'); 
end; 

它工作得很好寫這

create or replace 
procedure complex(datainput in VARCHAR2) 
is 
begin 
insert into dumtab values (datainput); 
end complex; 

SQL開發執行這一點,並將該值插入到表。但是,上述語句在數據分析工具中不受支持,所以我使用函數來代替。以下是編譯的函數的代碼。

create or replace 
function supercomplex(datainput in VARCHAR2) 
return varchar2 
is 
begin 
insert into dumtab values (datainput); 
return 'done'; 
end supercomplex; 

我再次試圖SQL開發執行它,但我得到不能在執行以下代碼

select supercomplex('somevalue') from dual; 

我的問題是 查詢內進行DML操作 - 我需要一個可以運行中提到的函數的語句SQL Developer或 - 一個可以執行我正在查找的功能的函數,可以通過select聲明。 - 如果不能做我在問什麼,我想要一個理由,以便我可以通知我的經理,因爲我非常新(比如一個星期?)PL/SQL,所以我不知道規則和語法。

P.S.我多麼希望這是C++或連渣:(

編輯

我需要運行在SQL Developer中的功能,因爲在DMine運行它(這是工具),以測試是否是前有效。任何在SQL無效也是無效的DMine,而不是周圍的其他方式。

感謝您的幫助,我瞭解情況,並,爲什麼它是非法的/不推薦

+0

您收到的錯誤不是SQL Developer特有的,它是一個Oracle錯誤,它非常簡單:您無法在查詢中對數據庫進行修改。據推測這是由於隔離水平,以保持ACID合規性;否則你可以同時修改你正在查詢的表格,並且所有的地獄都會破裂! – Xophmeister 2012-01-04 15:39:57

+0

你能解釋爲什麼你需要在SQL Developer中調用函數嗎?爲什麼這很重要?數據分析工具不支持 – APC 2012-01-04 15:40:18

+0

?什麼工具?如果您可以在此工具中運行SQL,則應該能夠運行腳本(最初顯示的匿名塊)。 – tbone 2012-01-04 18:37:17

回答

33

您可以使用指令pragma autonomous_transaction。這將把函數運行成一個獨立的事務,它將能夠在不引起ORA-14551的情況下執行DML。

請注意,由於autonomous transaction是獨立的,因此DML的結果將被提交到父事務處理範圍之外。在大多數情況下,這不會是一個可接受的解決方法。

SQL> CREATE OR REPLACE FUNCTION supercomplex(datainput IN VARCHAR2) 
    2  RETURN VARCHAR2 IS 
    3  PRAGMA AUTONOMOUS_TRANSACTION; 
    4 BEGIN 
    5  INSERT INTO dumtab VALUES (datainput); 
    6  COMMIT; 
    7  RETURN 'done'; 
    8 END supercomplex; 
    9/

Function created 

SQL> SELECT supercomplex('somevalue') FROM dual; 

SUPERCOMPLEX('SOMEVALUE') 
-------------------------------------------------------------------------------- 
done 

SQL> select * from dumtab; 

A 
-------------------------------------------------------------------------------- 
somevalue 

Tom Kyte has a nice explanation關於爲什麼錯誤首先出現。這是不安全的,因爲它可能取決於行處理的順序。此外,Oracle不保證該函數每行至少執行一次,最多執行一次。

10

只是聲明一個接受返回值的變量,例如:

declare 
    retvar varchar2(4); 
begin 
    retvar := supercomplex('somevalue'); 
end; 

select不起作用,因爲函數正在執行插入,如果它所做的只是返回一個值,那麼它將起作用。

+1

您忘記包含變量來保存返回的值。 – APC 2012-01-04 15:38:38