2009-07-10 46 views
17

Sé que somos raros, nosotros los pobres que estamos usando iSeries para DB2/AS400, pero espero que alguien pueda responder a esta simple pregunta. ¿Hay alguna manera de devolver el valor de identidad de una declaración de inserción sin usar dos líneas de SQL? Me veo obligado a usar SQL en línea en C# para realizar una inserción, y luego necesito usar la identidad generada para la inserción para algo más adelante. En pocas palabras, necesito el equivalente de iSeries DB2 del "DEVOLUCION" de Oracle. Es decir,iSeries DB2: ¿hay alguna manera de seleccionar el valor de identidad de una instrucción de inserción?

INSERT INTO AwesomeTable (column1, column2, etc.) 
    VALUES (value1, value2, etc.) 
    RETURNING something; 

¿Alguien? Gracias por adelantado.

EDITAR: A menos que alguien sepa de una manera que puedo ejecutar dos líneas de SQL en una IBM.Data.DB2.iSeries.iDB2Command (no un proceso almacenado), me gustaría hacer esto todo en una línea de SQL

+0

+1 Buena pregunta –

+0

¿Pudo resolver esto? En caso afirmativo, publique su respuesta. –

+0

@DamienJoe Ya no estoy usando iSeries y no tengo acceso a ningún sistema que pueda usar para probar estas respuestas. Si encuentra que uno de ellos funciona, por favor coméntelo aquí y marcaré la respuesta como aceptada. –

Respuesta

7

Necesita utilizar la función escalar IDENTITY_VAL_LOCAL. Desde el IBM documentation:

IDENTITY_VAL_LOCAL es una función no determinista que devuelve el último valor asignado a una columna de identidad.

Ejemplo:

CREATE TABLE EMPLOYEE 
    (EMPNO INTEGER GENERATED ALWAYS AS IDENTITY, 
    NAME CHAR(30), 
    SALARY DECIMAL(5,2), 
    DEPT SMALLINT) 

INSERT INTO EMPLOYEE 
    (NAME, SALARY, DEPTNO) 
    VALUES('Rupert', 989.99, 50) 

SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1 
+1

En el programa C#, probablemente agregaría lo siguiente como un segundo comando SQL: "select identity_val_local() de sysibm.sysdummy1" en lugar de la instrucción VALUES INTO en el ejemplo anterior. –

+0

Gracias, Tracy - buena sugerencia. He actualizado la respuesta. –

+0

Eso devolvería el campo de identidad insertado por la última operación realizada en cualquier tabla y no en esa tabla específica. ¿Imagine un entorno con muchos usuarios insertando en muchas tablas de columnas de identidad? –

13

No estoy seguro de iSeries, pero los siguientes trabajé en db2v8.1:

Considérese 'ID' es el nombre de la columna de identidad. La siguiente stmt devolverá el ID generado de nuevo (el mismo que se inserta por la prop de inserción):

SELECT ID FROM FINAL TABLE (
    INSERT INTO AwesomeTable (column1, column2, etc.) 
      VALUES (value1, value2, etc.)  
    ) 

Alguna explicación que encontré en el sitio publib: (he usado como referencia para poner a prueba mi consulta anterior)

 /* The following SELECT statement references an INSERT statement in its 
      FROM clause. It inserts an employee record from host variables into 
      table company_b. The current employee ID from the cursor is selected 
      into the host variable new_id. The keywords FROM FINAL TABLE 
      determine that the value in new_id is the value of ID after the 
      INSERT statement is complete. 

      Note that the ID column in table company_b is generated and without 
      the SELECT statement an additional query would have to be made in 
      order to retreive the employee's ID number. 
     */ 
     EXEC SQL SELECT ID INTO :new_id 
       FROM FINAL TABLE(INSERT INTO company_b 
       VALUES(default, :name, :department, :job, :years, :salary, 
         :benefits, :id)); 

Espero que esto ayude :)

+1

Sí, encontré esto también en el sitio público y no puedo conseguir que funcione con iSeries. Muchas gracias por tu respuesta. –

+1

¿Quiere decir que FINAL TABLE no es compatible con iSeries? –

+1

FINAL TABLE se admite a partir de la versión 6.1. Es el enfoque recomendado para determinar el valor de identidad utilizado por una declaración de inserción. –

0

He aquí un ejemplo:

CREATE TABLE AUTOINC (          
    AUTO91 INTEGER  GENERATED ALWAYS AS IDENTITY,   
    SCDS91 CHAR(35)  NOT NULL DEFAULT '',     
    MCLD91 DECIMAL(3,0) NOT NULL DEFAULT 0,      
    CONSTRAINT PK_AUTOINC PRIMARY KEY(AUTO91)); 

// Observe la palabra clave predeterminada donde se encuentra el campo de incremento automático.

insert into AUTOINC Values(default ,'SYSC' , 0) 

// Y usando la función para devolver el último valor de la columna de identidad.

// Nota: solo obtiene la primera fila.

select **IDENTITY_VAL_LOCAL**() from AUTOINC **fetch first row only** 
+0

... Esto es esencialmente un duplicado de una respuesta que se publicó aquí ** hace 2 años **. ¿Qué diferencia tu respuesta de eso? –

Cuestiones relacionadas