Solution "ne peut pas effectuer une opération DML à l'intérieur d'une requête"?

j'utilise un outil D'analyse de données et l'exigence que j'ai était d'accepter une valeur de l'Utilisateur, passer que comme un paramètre et le stocker dans une table. Pas très compliqué donc je me suis assis pour écrire ce

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

j'ai exécuté ce dans SQL Developer en utilisant la déclaration suivante

begin
complex('SomeValue');  
end;

cela a bien fonctionné, et la valeur a été insérée dans la table. Cependant, les énoncés ci-dessus ne sont pas pris en charge dans l'outil D'analyse des données, donc j'ai eu recours à un la fonction la place. Voici le code de la fonction, il compile.

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

une fois de plus j'ai essayé de l'exécuter en SQL Developer, mais j'ai eu impossible d'effectuer une opération DML à l'intérieur d'une requête lors de l'exécution du code suivant

select supercomplex('somevalue') from dual;

ma question Est - J'ai besoin d'une déclaration qui peut exécuter le mentionné fonction SQL Developer ou - Une fonction qui peut effectuer ce que je cherche et qui peut être exécutée par le select déclaration. - Si il n'est pas possible de faire ce que je demande, je voudrais une raison afin que je puisse informer mon manager que je suis très nouveau (comme une semaine?) à PL/SQL donc je ne suis pas au courant des règles et de syntaxes.

P. S. Comment je souhaite que ce était le C++ ou même Java :(

EDIT

j'ai besoin d'exécuter la fonction SQL Developer, car avant de l'exécuter dans DMine (qui est l'outil) afin de tester si elle est valide ou pas. Tout ce qui est invalide dans SQL est également invalide dans DMine, mais pas l'inverse.

Merci pour l'aide, j'ai compris la situation et pourquoi c'est illégal/pas recommandé

19
demandé sur Joshua1729 2012-01-04 19:20:16

2 réponses

Vous pouvez utiliser la directive pragma autonomous_transaction. Cela exécutera la fonction dans une transaction indépendante qui sera en mesure d'effectuer DML sans soulever L'ORA-14551.

soyez conscient que la opération autonome est indépendant, les résultats de la DML seront commentés en dehors de la portée de la transaction mère. Dans la plupart des cas ce ne serait pas une solution acceptable.

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 a une belle explication à propos de pourquoi l'erreur est déclenchée en premier lieu. Il n'est pas sûr car il peut dépendre de l'ordre dans lequel les lignes sont traitées. De plus, Oracle ne garantit pas que la fonction sera exécutée au moins une fois et au plus une fois par ligne.

35
répondu Vincent Malgrat 2012-01-04 16:29:15

il suffit de déclarer une variable pour accepter la valeur de retour, par exemple:

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

Le select ne fonctionne pas parce que la fonction exécute un insert, si tout ce qu'il a fait était retourner une valeur alors il fonctionnerait.

12
répondu John Doyle 2012-01-04 17:45:46