2016-06-12 24 views
5

Ho già letto sulle regole per le operazioni DML con viste in ORACLE. Molti di loro mi sembrano chiari, ma sono confuso riguardo alla funzione aggregata.Perché non riesco a eliminare righe da questa vista che ha funzione di aggregazione nella clausola select (ORACLE)?

Ad esempio, ho due tabelle.

   EMPLOYEES 
╔═══════════╦═════════════╦══════════╗ 
║ emp_id ║ salary ║ dept_id ║ 
╠═══════════╬═════════════╬══════════╣ 
║ 2134 ║ 2200  ║ 10 ║ 
║ 2327 ║ 3100  ║ 10 ║ 
║ 2428 ║ 4100  ║ 20 ║ 
║ 2637 ║ 1700  ║ 30 ║ 
╚═══════════╩═════════════╩══════════╝ 
     \ |/
     \|/ 
     | 
     | DEPARTMENTS 
╔═══════════╦═════════════╦══════════╗ 
║ dept_id ║ dname  ║ location ║ 
╠═══════════╬═════════════╬══════════╣ 
║ 10  ║    ║   ║ 
║ 20  ║    ║   ║ 
║ 30  ║    ║   ║ 
╚═══════════╩═════════════╩══════════╝ 

Desidero una visualizzazione che mostri lo stipendio medio degli impiegati per reparto. Così, ho eseguire questo SQL:

CREATE OR REPLACE VIEW dept_sals AS 
    SELECT d.dept_id, round(avg(e.salary)) AS avg_salary 
    FROM employees e 
     JOIN 
     departments d 
     ON (e.dept_id = d.dept_id) 
    GROUP BY d.dept_id; 

Ora ho una visione che sembra:

╔═══════════╦════════════╗ 
║ dept_id ║ avg_salary ║ 
╠═══════════╬════════════╣ 
║ 10  ║ 2650 ║ 
║ 20  ║ 4100 ║ 
║ 30  ║ 1700 ║ 
╚═══════════╩════════════╝ 

capisco perché non riesco a eseguire istruzioni di aggiornamento nei confronti di questo punto di vista. La colonna "avg_salary" non è un dato, è un'informazione generata dinamicamente. Ma perché non riesco a cancellare una riga da questa vista?

Se si tenta di eseguire:

delete from dept_sals where dept_id = 10; 

ottengo:

ORA-01732: data manipulation operation not legal on this view 

quello che sto pensando:

Base tavolo DIPARTIMENTI ha un uno-a-uno con le righe in questa vista. Immagino che Oracle possa ottenere {dept_id} dalla vista e generare SQL che cancella la riga corrispondente dalla tabella DEPARTMENTS. Ciò non danneggerebbe la coerenza delle tabelle in quanto le informazioni in "avg_salary" non sono dati, sono calcoli che possiamo gettare via in quanto il reparto con {dept_id} non esiste più.

+0

L'eliminazione da quella visualizzazione eliminerebbe logicamente le righe da più tabelle o solo una secondo la tua opinione? Anche se questa non è la risposta in quanto sarebbe proibita anche per una singola query raggruppata in una tabella –

+0

@ Martin Smith Sto cercando di capire come funzionano le visualizzazioni Oracle perché non capisco il motivo della limitazione dell'eliminazione in questa situazione. Ho testato un caso in cui una vista con SQL = due tabelle join, aveva entrambe le chiavi primarie dalle tabelle di base nelle sue righe: one-to-one e one-to-many. Potrei cancellare le righe da quella vista e in realtà sono state eliminate dalla tabella che aveva una relazione uno-a-uno. La tabella di base con una relazione uno a molti con la vista non è stata influenzata dall'eliminazione. Non riesco a capire perché Oracle non può fare la stessa cosa ad esempio con AVG. Sals. Penso che non abbia bisogno della tabella dei dipendenti per farlo. – Lynx

+2

A mio parere, Oracle non ha calcolato tutte le possibili situazioni (ci sono moltissime possibili situazioni con selezioni nelle query di visualizzazione) e ha appena inserito alcune regole di base che separano le visualizzazioni aggiornabili e non aggiornabili, per mitigare questo trigger creato da Oracle per INSTEAD OF rendere tale visualizzazione (se necessario) aggiornabile. – ivanzg

risposta

5

Quello che si sta specificando è una vista non aggiornabile in Oracle. Le regole che separano le viste aggiornabili e non aggiornabili sono qui specificate dalla documentazione di Oracle.

"Un punto di vista non può essere modificato da UPDATE, INSERT o DELETE se la query vista contiene uno dei seguenti costrutti:

A set operator 

A DISTINCT operator 

An aggregate or analytic function 

A GROUP BY, ORDER BY, MODEL, CONNECT BY, or START WITH clause 

A collection expression in a SELECT list 

A subquery in a SELECT list 

A subquery designated WITH READ ONLY 

Joins, with some exceptions, as documented in Oracle Database Administrator's Guide" 

link ->https://docs.oracle.com/cd/B19306_01/appdev.102/b14251/adfns_triggers.htm

Ciò che si vuole può essere e viene risolto utilizzando i trigger di Oracle INSTEAD OF

Problemi correlati