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

Oracle - RETURNING kombineret med aggregerede funktioner

Først og fremmest er dokumentation og faktisk funktionalitet lidt ude af sync, så "officielle kilder" vil ikke kaste lys over detaljerne.

Syntaktisk diagram for 10g R2 (https://docs.oracle .com/cd/B19306_01/appdev.102/b14261/returninginto_clause.htm ) er nedenfor

I 11g (https://docs.oracle.com/ cd/E11882_01/appdev.112/e25519/returninginto_clause.htm ) dette blev opdelt i to:static_returning_clause (til indsættelse, opdatering, sletning) og dynamic_returning_clause (til udførelse med det samme). Vi er interesserede i den til DML.

Så for 10g var der et enkelt række udtryk, som ifølge dokumentation er Udtryk, der returnerer en enkelt række af en tabel . Det er et subtilt spørgsmål, om DML-sætning skal påvirke en enkelt række, eller en enkelt række kan udledes efter udførelse af sætningen (f.eks. ved at bruge aggregerede funktioner). Jeg antager, at ideen var at bruge denne syntaks, når DML-operation påvirker enkelt række (i modsætning til bulk collect into ); bruger ikke aggregerede funktioner, som returnerer en enkelt række for berørte rækker.

Så aggregerede funktioner i tilbagevenden til klausul er ikke dokumenteret klart. Desuden kan der for 11g kun vises et kolonnenavn efter returnerende søgeord, så selv udtryk som abs(column_name) er ikke tilladt for ikke at nævne aggregate_function(column_name), selvom det i virkeligheden virker.

Så strengt taget er denne funktionalitet med samlede funktioner ikke dokumenteret, især for 11g, 12c, 18c, og du kan ikke stole på den.

I stedet kan du bruge "bulk collect into" (og indstille operatoren for at få et særskilt sæt af elementerne)

SQL> create type str_tab as table of varchar2(4000)
  2  /

Type created.

SQL> set serveroutput on
SQL> declare
  2    i int;
  3    a str_tab;
  4  begin
  5    delete from t returning val bulk collect into a;
  6    dbms_output.put_line('cnt all ' || a.count || ' cnt distinct ' || set(a).count);
  7    rollback;
  8  end;
  9  /
cnt all 4 cnt distinct 2

PL/SQL procedure successfully completed.

Vær også opmærksom på fejlmeddelelsen. Det står klart

Ikke bare "distinkt er ikke tilladt" som i dette eksempel

SQL> select listagg(distinct val) within group (order by val) str from t;
select listagg(distinct val) within group (order by val) str from t
       *
ERROR at line 1:
ORA-30482: DISTINCT option not allowed for this function


  1. Portering af Oracle PL/SQL til Snowflake uden JavaScript

  2. Installer PL/Java 1.5.2 i PostgreSQL 11

  3. Oracle-fejl ved opstart, endnu en opstarts-/nedlukningsoperation af denne instans i gang

  4. Hibernate uuid generation og mysql uuid funktion uuid()