2011-07-25 35 views
6

Estoy tratando de ajustar todas mis transacciones que deben ser todo o nada en BEGIN y COMMIT, pero no estoy seguro de cómo hacerlo en casos como el siguiente.Obteniendo una ID dentro de un bloque de transacción PostgreSQL

Tengo 3 tablas, una para imágenes, una para albums, y una para las relaciones entre ellas, es decir, album_images. La forma en que funciona el sistema es que un usuario puede crear un álbum y llenarlo con sus imágenes en una sola operación. El SQL es el siguiente:

BEGIN; 
    INSERT INTO albums [...]; -- Create a new album row 
    SELECT id AS album_id FROM albums WHERE [...]; -- Get that rows ID 
    -- Now use album_id in the next statement 
    INSERT INTO album_images (album_id, image_id) [...]; 
COMMIT; 

Esto es probablemente un problema común, es que no estoy seguro de qué buscar y me parece que no puede encontrar una solución en la documentación tampoco.

Respuesta

6

Como alternativa a la cláusula INSERT ... mencionado por Cody DEVOLUCIÓN, se puede utilizar el valor actual de la secuencia asociada con la columna de ID:

BEGIN; 
    INSERT INTO albums [...]; 
    INSERT INTO album_images (currval('albums_id_seq'), image_id) [...]; 
COMMIT; 

Esto supone el esquema de nomenclatura estándar de Postgres al crear la secuencia automáticamente para columnas definidas como serial.

Otra alternativa, si solo está utilizando una sola inserción, es utilizar la función lastval(). A continuación, ni siquiera necesidad de poner el nombre de la secuencia en la instrucción INSERT:

BEGIN; 
    INSERT INTO albums [...]; 
    INSERT INTO album_images (lastval(), image_id) [...]; 
COMMIT; 
+0

Hm, ambos ejemplos producen 'error de sintaxis en o cerca de" ("' para mí. Incluso si alguno de estos funciona eventualmente, supongo que no hay forma de utilizar el valor de 'album_id' de mi' SELECT'? – Steffen

+0

Oh, mi mal, funciona, gracias. – Steffen

2

Postgres proporciona una cláusula "RETORNO" utilizada en un INSERT para recuperar fácilmente la clave primaria recién creada.

http://www.postgresql.org/docs/8.3/interactive/sql-insert.html

Algunos ejemplos: http://6c62.net/blog/?p=48

+3

Gracias, pero mi problema no es tanto obtener esa ID, sino usarla en la siguiente declaración. Ese 'SELECCIONAR' en mi ejemplo es el código de trabajo real que devolverá la ID correcta. ¿O malinterpreté algo? Esos ejemplos están un poco sobre mi cabeza. – Steffen

+0

Cuando trato de usar un RETURNO con nombre dentro de otra declaración de la transacción arroja una "columna desconocida" errror ... No creo que esas variables se compartan dentro de la transacción. –

-1

que pueda obtener el id de la fila insertada como

INSERT INTO albums [...] returning album_id; 

Esto devolverá el album_id después de la inserción.

+0

Específicamente, el OP quiere usar el 'id' en la siguiente declaración en la transacción. La cláusula' RETURNING' no resuelve esto de manera independiente. –

Cuestiones relacionadas