2013-07-26 7 views
3

я получаю эту ошибку:Oracle: операция DML внутри запроса

cannot perform a DML operation inside a query 

, когда я пытался выполнить запрос

select st_atten_up(1,7) from dual; 

код ДАЛ ниже.

create or replace FUNCTION st_atten_up(stu_id IN student_info.id%type,app_mon IN student_attendence.month%type) 
RETURN NUMBER 
IS 
att1 NUMBER; 
BEGIN SELECT ATTENDANCE into att1 FROM student_attendence 
WHERE student_attendence.id = stu_id and student_attendence.month = app_mon; 
att1 := att1 + 1; 
UPDATE student_attendence SET ATTENDANCE = att1 
where id = stu_id and month = app_mon; 
return att1; 
END; 

Заранее спасибо.

+1

Используйте 'pragma autonomous_transaction;' внутри вашей функции, чтобы сделать ее вызываемой из инструкции 'select'. –

ответ

5

Вы можете технически выполнить DML внутри select, если вызванная функция была объявлена ​​как PRAGMA AUTONOMOUS_TRANSACTION (Link). Тем не менее, это редко хорошая идея, чтобы выполнить DML изнутри SELECT заявления по ряду веских причин, но, чтобы ответить на ваш вопрос, вы можете написать функцию с PRAGMA (в том числе изменяющих таблицы, снижения производительности.):

create or replace FUNCTION st_atten_up(stu_id IN student_info.id%type,app_mon IN student_attendence.month%type) 
RETURN NUMBER 
IS 
PRAGMA AUTONOMOUS_TRANSACTION; 
att1 NUMBER; 
BEGIN SELECT ATTENDANCE into att1 FROM student_attendence 
WHERE student_attendence.id = stu_id and student_attendence.month = app_mon; 
att1 := att1 + 1; 
UPDATE student_attendence SET ATTENDANCE = att1 
where id = stu_id and month = app_mon; 
return att1; 
END; 
+0

Заменить редко для никогда ... вызвать функцию несколько раз в SQL-заявлении и что происходит? Студент заканчивает 150% посещаемости ... – Ben

+0

@wolf благодарит его работу. Просто мне нужно добавить «commit», чтобы предотвратить >> ORA-06519: Активная автономная транзакция обнаружена и откат: – nixon1333

-1

Вы не можете вызвать функцию в DML, если сама функция имеет операцию DML.

Здесь вы бы хотели вызвать функцию в SELECT/UPDATE .. и вот почему она дает ошибку. Если вы хотите сделать это, создайте процедуру.