2009-07-02 17 views
13

In SQL Server, si possono fare cose come questa:Esiste un Oracle equivalente a OUTPUT INSERTED di SQL Server. *?

INSERT INTO some_table (...) OUTPUT INSERTED.* 
VALUES (...) 

In modo che è possibile inserire gli insiemi arbitrari di colonne/valori e ottenere quei risultati indietro. C'è un modo per farlo in Oracle?

Il meglio che posso venire in mente è questa:

INSERT INTO some_table (...) 
VALUES (...) 
RETURNING ROWID INTO :out_rowid 

... utilizzando: out_rowid come variabile bind. E quindi utilizzando una seconda query come questa:

SELECT * 
FROM some_table 
WHERE ROWID = :rowid 

... ma questo non è proprio la stessa cosa come si ritorna tutto all'interno della colonna, non solo le colonne ho inserito.

C'è un modo migliore per farlo senza utilizzare molto PL/SQL e preferibilmente con una sola query?

+1

Se sono le colonne a cui sei interessato (non i dati di riga) ... - Come stai derivando il (...)? Sicuramente a quel punto sai a quali colonne si fa riferimento nell'inserto? –

+0

Ho appena letto su OUTPUT INSERTED (http://msdn.microsoft.com/en-us/library/ms177564.aspx). Apparentemente ti permette di scegliere se i dati di riga restituiti sono quelli precedenti o successivi all'esecuzione di qualsiasi trigger di tabella. La clausola RETURNING di Oracle non supporta questo: ti dà solo i dati dopo che i trigger hanno avuto la possibilità di cambiarli. –

+0

@ Jeffrey Kemp - Vorrei sapere quali sono queste colonne. Tuttavia, dovrebbe essere il database. :-) –

risposta

3

La clausola RETURNING supporta la sintassi BULK COLLECT INTO. Considerare (10g):

SQL> CREATE TABLE t (ID NUMBER); 

Table created 
SQL> INSERT INTO t (SELECT ROWNUM FROM dual CONNECT BY LEVEL <= 5); 

5 rows inserted 
SQL> DECLARE 
    2  TYPE tab_rowid IS TABLE OF ROWID; 
    3  l_r tab_rowid; 
    4 BEGIN 
    5  UPDATE t SET ID = ID * 2 
    6  RETURNING ROWID BULK COLLECT INTO l_r; 
    7  FOR i IN 1 .. l_r.count LOOP 
    8  dbms_output.put_line(l_r(i)); 
    9  END LOOP; 
10 END; 
11/

AADcriAALAAAAdgAAA 
AADcriAALAAAAdgAAB 
AADcriAALAAAAdgAAC 
AADcriAALAAAAdgAAD 
AADcriAALAAAAdgAAE 

Funziona con più righe UPDATE e DELETE con la mia versione (10.2.0.3.0), ma NON con INSERT:

SQL> DECLARE 
    2  TYPE tab_rowid IS TABLE OF ROWID; 
    3  l_r tab_rowid; 
    4 BEGIN 
    5  INSERT INTO t (SELECT ROWNUM FROM dual CONNECT BY LEVEL <= 5) 
    6  RETURNING ROWID BULK COLLECT INTO l_r; 
    7  FOR i IN 1 .. l_r.count LOOP 
    8  dbms_output.put_line(l_r(i)); 
    9  END LOOP; 
10 END; 
11/

ORA-06550: line 7, column 5: 
PL/SQL: ORA-00933: SQL command not properly ended 

Forse hai un altro versione recente (11g?) e il BULK COLLECT INTO è supportato per più righe INSERT s?

+0

Non sono molto preoccupato per il numero di righe perché sono il numero di colonne. Il numero di righe sarà praticamente sempre uno mentre le colonne saranno variabili. –

+0

@Jason: Penso che dovrai usare dbms_sql se il numero di colonne è variabile/non noto al momento della compilazione –

5

Forse non capisco la domanda, ma non lo farebbe? (È necessario sapere cosa si vuole di nuovo)

INSERT INTO some_table (...) 
VALUES (...) 
RETURNING some_column_a, some_column_b, some_column_c, ... INTO :out_a, :out_b, :out_c, ... 

@Vincent ritorno di massa raccogliere in per l'inserimento più file funziona solo in combinazione con forall (In altre parole se si inserisce da collezione è possibile recuperare "risultati" in un altro)

Problemi correlati