Je n'arrive pas à comprendre la syntaxe correcte pour le pseudo-SQL suivant:
INSERT INTO some_table
(column1,
column2)
SELECT col1_value,
col2_value
FROM other_table
WHERE ...
RETURNING id
INTO local_var;
Je voudrais insérer quelque chose avec les valeurs d'une sous-requête. Après l'insertion, j'ai besoin du nouvel identifiant généré.
Voici ce que dit le doc Oracle:
OK, je pense que ce n'est pas possible uniquement avec la clause values ... Y a-t-il une alternative?
Vous ne pouvez pas utiliser le RETURNING BULK COLLECT à partir d'un INSERT. Cette méthodologie peut fonctionner avec des mises à jour et des suppressions:
create table test2(aa number)
/
insert into test2(aa)
select level
from dual
connect by level<100
/
set serveroutput on
declare
TYPE t_Numbers IS TABLE OF test2.aa%TYPE
INDEX BY BINARY_INTEGER;
v_Numbers t_Numbers;
v_count number;
begin
update test2
set aa = aa+1
returning aa bulk collect into v_Numbers;
for v_count in 1..v_Numbers.count loop
dbms_output.put_line('v_Numbers := ' || v_Numbers(v_count));
end loop;
end;
Vous pouvez le faire fonctionner avec quelques étapes supplémentaires (faire un FORALL INSERT en utilisant TREAT) Comme décrit dans cet article:
T
utiliser l'exemple qu'ils créent et l'appliquer à la table de test test2
CREATE or replace TYPE ot AS OBJECT
( aa number);
/
CREATE TYPE ntt AS TABLE OF ot;
/
set serveroutput on
DECLARE
nt_passed_in ntt;
nt_to_return ntt;
FUNCTION pretend_parameter RETURN ntt IS
nt ntt;
BEGIN
SELECT ot(level) BULK COLLECT INTO nt
FROM dual
CONNECT BY level <= 5;
RETURN nt;
END pretend_parameter;
BEGIN
nt_passed_in := pretend_parameter();
FORALL i IN 1 .. nt_passed_in.COUNT
INSERT INTO test2(aa)
VALUES
( TREAT(nt_passed_in(i) AS ot).aa
)
RETURNING ot(aa)
BULK COLLECT INTO nt_to_return;
FOR i IN 1 .. nt_to_return.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(
'Sequence value = [' || TO_CHAR(nt_to_return(i).aa) || ']'
);
END LOOP;
END;
/
Malheureusement ce n'est pas possible. RETURNING n'est disponible que pour les instructions INSERT ... VALUES. Voir ce fil de discussion Oracle pour une discussion à ce sujet.
Comme l'insertion est basée sur une sélection, Oracle suppose que vous autorisez une insertion de plusieurs lignes avec cette syntaxe. Dans ce cas, examinez la version à plusieurs lignes du document de clause de retour car elle montre que vous devez utiliser BULK COLLECT pour récupérer la valeur de toutes les lignes insérées dans une collection de résultats.
Après tout, si votre requête d’insertion crée deux lignes, quelle valeur retournée mettrait-elle dans une seule variable?
EDIT - Il s'avère que cela ne fonctionne pas comme je l'avais pensé .... sacrément!