Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Oracle - RETURNING dikombinasikan dengan fungsi agregat

Pertama-tama, dokumentasi dan fungsionalitas sebenarnya agak tidak sinkron sehingga "sumber resmi" tidak akan menjelaskan detailnya.

Diagram sintaks untuk 10g R2 (https://docs.Oracle .com/cd/B19306_01/appdev.102/b14261/returninginto_clause.htm ) ada di bawah

Dalam 11g (https://docs.Oracle.com/ cd/E11882_01/appdev.112/e25519/returninginto_clause.htm ) ini dibagi menjadi dua:static_returning_clause (untuk menyisipkan, memperbarui, menghapus) dan dynamic_returning_clause (untuk segera dieksekusi). Kami tertarik dengan yang untuk DML.

Jadi untuk 10g ada satu baris ekspresi yang menurut dokumentasi adalah Ekspresi yang mengembalikan satu baris tabel . Ini adalah pertanyaan halus apakah pernyataan DML harus memengaruhi satu baris atau satu baris dapat diturunkan setelah eksekusi pernyataan (katakanlah, dengan menggunakan fungsi agregat). Saya berasumsi idenya adalah menggunakan sintaks ini ketika operasi DML memengaruhi satu baris (sebagai lawan dari bulk collect into ); tidak menggunakan fungsi agregat yang mengembalikan satu baris untuk baris yang terpengaruh.

Jadi fungsi agregat dalam kembali ke klausa tidak didokumentasikan dengan jelas. Selain itu, untuk 11g hanya nama kolom yang mungkin muncul setelah mengembalikan kata kunci, sehingga ekspresi seperti abs(column_name) tidak diperbolehkan, apalagi agregat_function(column_name), meskipun dalam kenyataannya berfungsi.

Jadi, sebenarnya, fungsi dengan fungsi agregat ini tidak didokumentasikan, terutama untuk 11g, 12c, 18c dan Anda tidak dapat mengandalkannya.

Sebagai gantinya, Anda dapat menggunakan "kumpulkan massal ke dalam" (dan setel operator untuk mendapatkan set elemen yang berbeda)

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.

Perhatikan juga pesan kesalahan. Jelas tertulis

Bukan hanya "membedakan tidak diperbolehkan" seperti dalam contoh ini

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. Bagaimana cara menambahkan spasi di depan nomor saya jika itu adalah satu digit?

  2. SQL yang baru saja dieksekusi bukan di V$SQL

  3. Pengidentifikasi tidak valid Oracle tidak mengerti string

  4. ES Gratis untuk 11.2.0.4 dan 12.2 Tanggal Rilis

  5. cx_Oracle dan Penanganan Pengecualian - Praktik yang baik?