Подтвердить что ты не робот

Решение проблемы "не может выполнить операцию DML внутри запроса"?

Я использую инструмент анализа данных, и я должен был принять значение от пользователя, передать это как параметр и сохранить его в таблице. Довольно напряженный, поэтому я сидел, чтобы написать это

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

Я выполнил это в SQL Developer, используя следующую инструкцию

begin
complex('SomeValue');  
end;

Он работал нормально, и значение было вставлено в таблицу. Однако приведенные выше утверждения не поддерживаются в инструменте Data Analysis, поэтому я прибегнул к использованию функции. Ниже приведен код функции, который он компилирует.

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

Снова я попытался выполнить его в SQL Developer, но я получил , не выполнив операцию DML внутри запроса после выполнения следующего кода

select supercomplex('somevalue') from dual;

Мой вопрос: - Мне нужно выражение, которое может запустить указанную функцию в SQL Developer или - Функция, которая может выполнять то, что я ищу, которое может быть выполнено оператором select. - Если невозможно сделать то, что я прошу, я бы хотел повести, чтобы я мог сообщить своему менеджеру, как я очень новый (например, неделю назад?) В PL/SQL, поэтому я не знаю правил и синтаксисы.

P.S. Как бы я хотел, чтобы это был С++ или даже Java: (

ИЗМЕНИТЬ

Мне нужно запустить функцию на SQL Developer, потому что перед ее запуском в DMine (который является инструментом), чтобы проверить, действительно ли это или нет. Все, что недействительно в SQL, также неверно в DMine, но не наоборот.

Спасибо за помощь, я понял ситуацию и почему она незаконна/не рекомендуется

4b9b3361

Ответ 1

Вы можете использовать директиву pragma autonomous_transaction. Это запустит эту функцию в независимую транзакцию, которая сможет выполнять DML без повышения ORA-14551.

Имейте в виду, что поскольку автономная транзакция независима, результаты 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 имеет приятное объяснение о том, почему ошибка возникает в первую очередь. Это не безопасно, потому что это может зависеть от порядка обработки строк. Кроме того, Oracle не гарантирует, что функция будет выполняться как минимум один раз и не более одного раза в строке.

Ответ 2

Просто объявите переменную для принятия возвращаемого значения, например:

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

Выбор не работает, потому что функция выполняет вставку, если все, что она сделала, это вернуть значение, то оно будет работать.