sql >> Database teknologi >  >> RDS >> Oracle

Alternativ til RETURNERING med INSERT...SELECT

Du bruger insert into ... select from konstruere. Så potentielt vil din erklæring indsætte mere end én række, hvilket betyder, at din RETURNING-klausul vil returnere mere end én række. Derfor skal du bruge BULK COLLECT-syntaksen til at udfylde en samling af nye nøgler.

Så vi prøver noget som dette ...

declare
    /* NB: define this collection using the appropriate name  */
    type new_keys is table of table_xxx.cola%type;
    col_res new_keys;
begin
    INSERT INTO TBL_XXX
    SELECT COLA * 10, COLB, COLC FROM TBL_YYY
    RETURNING table_xxx.COLA bulk collect INTO COL_RES;
end;
/

... kun for at få:

Jamen det stinker.

Desværre, mens RETURNING BULK COLLECT INTO fungerer med opdateringer og sletninger, fungerer det ikke med inserts (eller sammenlægninger kommer til det). Jeg er sikker på, at der er meget fornuftige grunde i Oracle-kernens interne arkitektur, men dette burde virke, og at det ikke gør det, er meget irriterende.

Uanset hvad, som @PonderStibbons påpegede, er der en løsning:FORALL-konstruktionen.

declare
    type new_rows is table of tbl_xxx%rowtype;
    rec_xxx new_rows;
    type new_keys is table of tbl_xxx.cola%type;
    col_xxx new_keys;
begin
    select cola * 10, colb, colc 
    bulk collect into rec_xxx
    from tbl_yyy;

    forall idx in 1 .. rec_xxx.count()
        insert into tbl_xxx
        values rec_xxx(idx)
        returning tbl_xxx.cola bulk collect into col_xxx
    ;

    for idx in 1 .. rec_xxx.count() loop
        dbms_output.put_line('tbl_xxx.cola = ' || col_xxx(idx));
   end loop;
end;
/

Her er en LiveSQL-demo (gratis OTN-login påkrævet) .




  1. Tilslutning af Oracle til SQL Server via databaselink

  2. Få første dato på måneden i postgres

  3. PHP &MySQL:Hvordan kan jeg bruge SET @rank=0; i $query=

  4. Forespørgselskolonne med char-datatype i oracle