2009-07-02 28 views
13

En SQL Server, puede hacer cosas como esta:¿Existe un Oracle equivalente a OUTPUT INSERTED de SQL Server. *?

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

Así que se puede insertar conjuntos arbitrarios de columnas/valores y obtener los resultados de vuelta. ¿Hay alguna forma de hacer esto en Oracle?

Lo mejor que puedo llegar a es la siguiente:

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

... usando: out_rowid como una variable de vinculación. Y a continuación, utilizando una segunda consulta como esta:

SELECT * 
FROM some_table 
WHERE ROWID = :rowid 

... pero esto no es exactamente lo mismo que se vuelve todo dentro de la columna, no sólo las columnas he insertado.

¿Hay alguna forma mejor de hacer esto sin usar una gran cantidad de PL/SQL y preferiblemente con sólo una consulta?

+1

Si son las columnas que le interesan (no los datos de la fila) ... - ¿Cómo se deriva el (...)? Seguramente en ese momento, ¿sabes a qué columnas se hace referencia en el inserto? –

+0

Acabo de leer en OUTPUT INSERTED (http://msdn.microsoft.com/en-us/library/ms177564.aspx). Aparentemente le permite elegir si los datos de la fila devueltos son anteriores o posteriores a la ejecución de cualquier desencadenante de tabla. La cláusula RETURNING de Oracle no es compatible con esto, solo le da los datos una vez que los desencadenantes han tenido la oportunidad de cambiarlos. –

+0

@ Jeffrey Kemp - Sabría cuáles son esas columnas. Sin embargo, también debería hacerlo la base de datos. :-) –

Respuesta

3

La cláusula RETURNING admite el BULK COLLECT INTO synthax. Considere (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 

Funciona con varias filas UPDATE y DELETE con mi versión (10.2.0.3.0), pero NO 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 

tal vez tenga un mayor la versión más reciente (11g?) y BULK COLLECT INTO es compatible con varias filas INSERT s?

+0

No estoy tan preocupado por el número de filas como por el número de columnas. El número de filas casi siempre será uno, mientras que las columnas serán variables. –

+0

@Jason: creo que deberás usar dbms_sql si el número de columnas es variable/desconocido en el momento de la compilación –

5

Tal vez no entiendo la pregunta, pero ¿no lo haría? (Usted debe saber lo que quiere de vuelta)

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

@Vincent mayor regresar a recoger en varias filas para insertar sólo funciona en conjunción con forall (en otras palabras, si se inserta de la colección se puede recuperar "resultados" en otro)

Cuestiones relacionadas