ORA-14551: impossible d'effectuer une opération DML à l'intérieur d'une requête
J'ai le texte suivant à l'intérieur d'un package
et il me donne une erreur:
ORA-14551: cannot perform a DML operation inside a query
Code est:
DECLARE
CURSOR F IS
SELECT ROLE_ID
FROM ROLE
WHERE GROUP = 3
ORDER BY GROUP ASC;
BEGIN
FOR R IN F LOOP
DELETE FROM my_gtt_1;
COMMIT;
INSERT INTO my_gtt_1
( USER, role, code, status )
(SELECT
trim(r.user), r.role, r.code, MAX(status_id)
FROM
table1 r,
tabl2 c
WHERE
r.role = R.role
AND r.code IS NOT NULL
AND c.group = 3
GROUP BY
r.user, r.role, r.code);
SELECT c.role,
c.subgroup,
c.subgroup_desc,
v_meb_cnt
INTO record_type
FROM ROLE c
WHERE c.group = '3' and R.role = '19'
GROUP BY c.role,c.subgroup,c.subgroup_desc;
PIPE ROW (record_type);
END LOOP;
END;
J'appelle le paquet comme ça dans un de mes procédures...:
OPEN cv_1 for SELECT * FROM TABLE(my_package.my_func);
comment puis-je éviter ce ORA-14551
erreur?
Pour info je n'ai pas collé le code à l'intérieur de la boucle. Fondamentalement, à l'intérieur de la boucle que je suis entrer dans des trucs dans la GTT, en supprimant des trucs de GTT et ensuite de sélectionner des éléments de GTT et en les ajoutant à un curseur.
OriginalL'auteur learn_plsql | 2010-07-19
Vous devez vous connecter pour publier un commentaire.
Le sens de l'erreur est assez clair: si nous appeler une fonction d'une instruction SELECT, il ne peut pas exécuter des instructions DML, c'est-à INSERT, UPDATE ou DELETE, ou, en effet, des instructions DDL.
Maintenant, l'extrait de code que vous avez posté contient un appel à la PIPE LIGNE, afin que, manifestement, vous appelez ce que SELECT * from TABLE(). Mais il comprend SUPPRIMER et INSÉRER des énoncés clairement, il tombe sous le coup de la pureté des niveaux requis pour les fonctions dans les instructions SELECT.
Donc, vous devez supprimer ces instructions DML. Vous les utilisez pour remplir une table temporaire globale, mais c'est une bonne nouvelle. Vous n'avez pas contenir tout le code qui utilise la GTT de sorte qu'il est difficile d'être sûr, mais à l'aide de Gtt est souvent inutile. Avec plus de détails, nous pouvons proposer des solutions de contournement.
Est-ce lié à cette autre question de la vôtre? Si oui, avez-vous suivi mes conseils pour vérifier la réponse que j'avais donnée à une question similaire?
Par souci d'exhaustivité, il est possible d'inclure DML et DDL les instructions dans une fonction appelée dans une instruction SELECT. La solution de contournement consiste à utiliser le AUTONOMOUS_TRANSACTION pragma. C'est rarement une bonne idée, et n'auraient certainement pas aider à ce scénario. Parce que la transaction est autonome les changements qu'il apporte sont invisibles à l'appel de la transaction. Sens dans ce cas que la fonction ne peut pas voir le résultat de la suppression ou insertion dans le GTT.
OriginalL'auteur APC
L'erreur signifie que vous sélectionnez à partir d'une fonction qui modifie les données (DELETE, INSERT dans votre cas).
Supprimer les instructions de modification des données de cette fonction dans une autre SP, si vous avez besoin de cette fonctionnalité. (Je suppose que je ne comprends pas à partir de l'extrait de code de pourquoi vous voulez supprimer et insérer à l'intérieur de la boucle)
OriginalL'auteur devio