sql >> Databáze >  >> RDS >> Oracle

Oracle - NÁVRAT v kombinaci s agregačními funkcemi

Za prvé, dokumentace a skutečná funkčnost jsou trochu nesynchronizované, takže "oficiální zdroje" nevrhnou světlo na detaily.

Syntaktický diagram pro 10g R2 (https://docs.oracle .com/cd/B19306_01/appdev.102/b14261/returninginto_clause.htm ) je níže

V 11 g (https://docs.oracle.com/ cd/E11882_01/appdev.112/e25519/returninginto_clause.htm ) to bylo rozděleno do dvou:static_returning_clause (pro vložení, aktualizaci, odstranění) a dynamic_returning_clause (pro okamžité provedení). Máme zájem o ten pro DML.

Takže pro 10g existoval jednořádkový výraz, který je podle dokumentace Výraz, který vrací jeden řádek tabulky . Je to jemná otázka, zda příkaz DML musí ovlivnit jeden řádek, nebo lze jeden řádek odvodit po provedení příkazu (řekněme pomocí agregačních funkcí). Předpokládám, že myšlenkou bylo použít tuto syntaxi, když operace DML ovlivňuje jeden řádek (na rozdíl od bulk collect into ); nepoužívat agregační funkce, které vracejí jeden řádek pro ovlivněné řádky.

Takže agregační funkce při návratu do klauzule nejsou jasně zdokumentovány. Navíc u 11g se po vrácení klíčového slova může objevit pouze název sloupce, takže ani výraz jako abs(název_sloupce) nesmí nezmiňovat agregovanou funkci (název_sloupce), i když ve skutečnosti to funguje.

Přesně řečeno, tato funkčnost s agregačními funkcemi není zdokumentována, zejména pro 11g, 12c, 18c a nelze se na ni spolehnout.

Místo toho můžete použít "hromadné shromažďování do" (a nastavit operátor, abyste získali odlišnou sadu prvků)

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ěnujte také pozornost chybovému hlášení. Jasně to říká

Nejen "rozlišovat není povoleno" jako v tomto příkladu

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. Instalace SQL Server 2017 krok za krokem -1

  2. MySQL:Neplatná data GIS poskytnutá funkci st_geometryfromtext

  3. Důsledky na výkon používání (DBMS_RLS) Oracle Row Level Security (RLS)?

  4. Jak přidat certifikát SSL (ca-cert) do proměnných prostředí node.js, abyste se mohli připojit k databázi Digital Ocean Postgres Managed Database?