Oracle
 sql >> база данни >  >> RDS >> Oracle

Oracle - ВРЪЩАНЕ в комбинация с агрегатни функции

На първо място, документацията и действителната функционалност малко не са синхронизирани, така че "официалните източници" няма да хвърлят светлина върху подробностите.

Синтактична диаграма за 10g R2 (https://docs.oracle .com/cd/B19306_01/appdev.102/b14261/returninginto_clause.htm ) е по-долу

В 11g (https://docs.oracle.com/ cd/E11882_01/appdev.112/e25519/returninginto_clause.htm ) това беше разделено на две:static_returning_clause (за вмъкване, актуализиране, изтриване) и dynamic_returning_clause (за незабавно изпълнение). Интересуваме се от този за DML.

Така че за 10g имаше израз с един ред, който според документацията е Израз, който връща един ред от таблица . Това е тънък въпрос дали DML изразът трябва да засегне един ред или един ред може да бъде извлечен след изпълнението на оператора (да речем чрез използване на агрегатни функции). Предполагам, че идеята е била да се използва този синтаксис, когато DML операцията засяга един ред (за разлика от bulk collect into ); без използване на агрегатни функции, които връщат един ред за засегнатите редове.

Така че агрегатните функции при връщане в клауза не са документирани ясно. Освен това за 11g може да се появи само име на колона след връщане на ключова дума, така че дори израз като abs(име_на_колона) не е позволен, без да се споменава aggregate_function(име_на_колона), въпреки че в действителност работи.

Така че, строго погледнато, тази функционалност с агрегатни функции не е документирана, особено за 11g, 12c, 18c и не можете да разчитате на нея.

Вместо това можете да използвате „bulk collect into“ (и оператор set, за да получите отделен набор от елементи)

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.

Обърнете внимание и на съобщението за грешка. Ясно се казва

Не просто „разграничаването не е позволено“ като в този пример

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. DatabaseMetaData.getColumns връща празен ResultSet за синоними

  2. копиране от една база данни в друга с помощта на oracle sql developer - връзката неуспешна

  3. Как да създадете вложена таблица с помощта на потребителски дефиниран тип данни в базата данни на Oracle

  4. Как да ограничим резултатите в Oracle

  5. Има ли начин да се използва Linq to Oracle