sql >> Databasteknik >  >> RDS >> Oracle

Oracle - RETURNERING kombinerat med aggregerade funktioner

För det första är dokumentation och faktisk funktionalitet lite osynkroniserad så "officiella källor" kommer inte att kasta ljus över detaljerna.

Syntaktisk diagram för 10g R2 (https://docs.oracle .com/cd/B19306_01/appdev.102/b14261/returninginto_clause.htm ) är nedan

I 11g (https://docs.oracle.com/ cd/E11882_01/appdev.112/e25519/returninginto_clause.htm ) detta delades upp i två:static_returning_clause (för att infoga, uppdatera, ta bort) och dynamic_returning_clause (för exekvera omedelbart). Vi är intresserade av den för DML.

Så för 10g fanns det ett uttryck med en rad som enligt dokumentationen är Uttryck som returnerar en enda rad i en tabell . Det är en subtil fråga om DML-satsen måste påverka en enskild rad eller enstaka rad kan härledas efter exekvering av satsen (säg genom att använda aggregerade funktioner). Jag antar att tanken var att använda denna syntax när DML-operation påverkar en rad (i motsats till bulk collect into ); använder inte aggregerade funktioner som returnerar en rad för berörda rader.

Så aggregerade funktioner vid återkomst till klausul dokumenteras inte tydligt. Dessutom, för 11g kan bara ett kolumnnamn visas efter att ha returnerat nyckelordet, så även uttryck som abs(kolumnnamn) är inte tillåtet att inte nämna aggregate_function(kolumnnamn), även om det i verkligheten fungerar.

Så strängt taget är denna funktionalitet med aggregerade funktioner inte dokumenterad, särskilt för 11g, 12c, 18c och du kan inte lita på det.

Istället kan du använda "bulk collect into" (och ställa in operatorn för att få en distinkt uppsättning av elementen)

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.

Var också uppmärksam på felmeddelandet. Det står tydligt

Inte bara "distinkt är inte tillåtet" som i det här exemplet

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. Hur kan jag göra flera order_by i Flask-SQLAlchemy?

  2. Motsvarighet till MySQL PÅ DUPLIKATNYCKELUPPDATERING i SQL Server

  3. Docker-behållare för Postgres 9.1 exponerar inte port 5432 för värd

  4. Överväganden kring kolumnordning i index och sorteringar