Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Oracle - POWRÓT w połączeniu z funkcjami agregacyjnymi

Po pierwsze, dokumentacja i rzeczywista funkcjonalność są nieco niezsynchronizowane, więc „oficjalne źródła” nie rzucą światła na szczegóły.

Diagram składniowy dla 10g R2 (https://docs.oracle .com/cd/B19306_01/appdev.102/b14261/returninginto_clause.htm ) znajduje się poniżej

W 11g (https://docs.oracle.com/ cd/E11882_01/appdev.112/e25519/returninginto_clause.htm ) zostało to podzielone na dwie części:static_returning_clause (do wstawiania, aktualizacji, usuwania) i dynamic_returning_clause (do natychmiastowego wykonania). Interesuje nas ten dotyczący DML.

Tak więc dla 10g było jednowierszowe wyrażenie, które zgodnie z dokumentacją to Wyrażenie, które zwraca pojedynczy wiersz tabeli . Jest to subtelne pytanie, czy instrukcja DML musi wpływać na pojedynczy wiersz, czy pojedynczy wiersz można wyprowadzić po wykonaniu instrukcji (powiedzmy, za pomocą funkcji agregujących). Zakładam, że pomysł polegał na użyciu tej składni, gdy operacja DML wpływa na pojedynczy wiersz (w przeciwieństwie do bulk collect into ); nie używa funkcji agregujących, które zwracają pojedynczy wiersz dla wierszy, których dotyczy problem.

Tak więc funkcje agregujące w powrocie do klauzuli nie są jasno udokumentowane. Co więcej, dla 11g po zwróceniu słowa kluczowego może pojawić się tylko nazwa kolumny, więc nawet wyrażenie takie jak abs(nazwa_kolumny) nie może nie wspomnieć o funkcji zagregowanej(nazwa_kolumny), mimo że w rzeczywistości to działa.

Tak więc, ściśle mówiąc, ta funkcjonalność z funkcjami agregacji nie jest udokumentowana, szczególnie dla 11g, 12c, 18c i nie można na niej polegać.

Zamiast tego możesz użyć "zbierz zbiorczo do" (i operatora set, aby uzyskać odrębny zestaw elementów)

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.

Zwróć także uwagę na komunikat o błędzie. Wyraźnie mówi

Nie tylko „różnice nie są dozwolone”, jak w tym przykładzie

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. Czy mogę mieć ograniczenie dotyczące liczby odrębnych wartości w kolumnie w SQL?

  2. Jak skompresować ten zestaw wyników Oracle do wartości zgodnie z priorytetem wiersza, ignorując wartości null?

  3. Jak znaleźć zduplikowane wartości w tabeli w Oracle?

  4. pobierz wynik z zapytania

  5. ORA-02019:nie znaleziono opisu połączenia do zdalnej bazy danych