2012-02-17 18 views
11

Sto tentando di replicare un comando "update tbl1 from tbl2" di Ingres, che non esiste esattamente in Oracle.Oracle - aggiornamento join - tabella non protetta da chiavi

Quindi utilizzo il comando "aggiorna (seleziona tbl1 join tbl2 ...)". Entrambe le tabelle hanno le chiavi primarie definite e I ha pensato che il mio join identificasse in modo univoco le righe, ma sto ancora ottenendo "ORA-01779: impossibile modificare una colonna che esegue il mapping su una tabella non conservata con chiave".

Qui sono opportunamente anonimi definizioni di tabella e l'aggiornamento sto cercando di eseguire:

CREATE TABLE tbl1 
(
    ID decimal(11) NOT NULL, 
    A varchar2(3) NOT NULL, 
    B float(7), 
    CONSTRAINT tbl1_pk PRIMARY KEY (ID,A) 
) 
; 

CREATE TABLE tbl2 
(
    ID decimal(11) NOT NULL, 
    A varchar2(3) NOT NULL, 
    B float(15), 
    C float(15), 
    D char(1) NOT NULL, 
    CONSTRAINT tbl2_PK PRIMARY KEY (ID,A,D) 
) 
; 

UPDATE 
    (select tbl1.b, tbl2.c 
    from tbl1 inner join tbl2 
    on tbl1.id=tbl2.id 
    and tbl1.a=tbl2.a 
    and tbl1.b=tbl2.b 
    and tbl1.a='foo' 
    and tbl2.D='a') 
set b=c; 

Come posso definire il mio selezionare in modo tale che Oracle sarà soddisfatto che non ho violazioni unicità?

risposta

18

Si dovrebbe essere in grado di fare questo con una subquery correlata

UPDATE tbl1 t1 
    SET t1.b = (SELECT c 
       FROM tbl2 t2 
       WHERE t1.id = t2.id 
        AND t1.a = t2.a 
        AND t1.b = t2.b 
        AND t2.d = 'a') 
WHERE t1.a = 'foo' 
    AND EXISTS(SELECT 1 
       FROM tbl2 t2 
       WHERE t1.id = t2.id 
        AND t1.a = t2.a 
        AND t1.b = t2.b 
        AND t2.d = 'a') 

Il problema con il UPDATE che hai scritto è che Oracle non può garantire che non v'è esattamente 1 tbl2.c valore che corrisponde ad un singolo tbl1.b valore. Se ci sono più righe in tbl2 per qualsiasi riga specifica in tbl1, l'aggiornamento correlato genererà un errore che indica che una sottoquery a riga singola ha restituito più righe. In tal caso, è necessario aggiungere una logica alla sottoquery per specificare quale riga da tbl2 utilizzare in quel caso.

+0

Questo sembra risolvere il problema - e grazie per l'ulteriore spiegazione. Ha senso. –

1

Questa istruzione ha esito negativo con un errore (ORA-01779 non può modificare una colonna che esegue il mapping su una tabella non conservata con chiave), perché tenta di modificare la base tbl1table e la tabella tbl1 non è protetta dalla chiave nella vista . perché sebbene (ID, A) sia una chiave della tabella dept, non è una chiave del join.

+0

Il link non esiste più, potresti aggiornare o riepilogare le informazioni dalla pagina corretta? – Kosi2801

+0

Esiste ancora, ma ora è http://docs.oracle.com/cd/E11882_01/server.112/e25494/views.htm#ADMIN11783. Si riferisce a: Oracle 11.2 Manuale dell'amministratore del database -> § 24 Gestione di viste, sequenze e sinonimi -> §§ Tabelle conservate a chiave – user1136452

Problemi correlati