2009-05-22 17 views

Respuesta

38
select nextval('mytable_seq') from generate_series(1,3); 

generate_series es una función que devuelve el número de filas con números secuenciales, configurados por sus argumentos.

En el ejemplo anterior, no nos importa el valor en cada fila, solo usamos generate_series como generador de filas. Y para cada fila podemos llamar a nextval. En este caso, devuelve 3 números (nextvals).

Puede ajustar esto en la función, pero no estoy seguro de si es realmente razonable dado lo breve que es la consulta.

+0

¡EXACTAMENTE lo que estaba buscando, gracias! –

+3

Tenga en cuenta que los 3 numbres (nextvals) no se garantiza que sean secuenciales. – cquezel

0

Mi mejor solución actual es:

SELECT NEXTVAL('mytable_seq') AS id 
UNION ALL 
SELECT NEXTVAL('mytable_seq') AS id 
UNION ALL 
SELECT NEXTVAL('mytable_seq') AS id; 

Qué devolverá correctamente 3 filas ... pero me gustaría algo que sea SQL mínimo incluso para 100 o más NEXTVAL invo cationes

1

CREATE OR REPLACE FUNCTION foo() RETURNS SETOF INT AS $$ 
DECLARE 
    seqval int; x int; 
BEGIN 
x := 0; 

WHILE x < 100 LOOP 
    SELECT into seqval nextval('f_id_seq'); 
    RETURN NEXT seqval; 
    x := x+1; 
END LOOP; 
RETURN; 
END; 
$$ LANGUAGE plpgsql STRICT; 

Por supuesto, si todo lo que estamos tratando de hacer es avanzar en la secuencia, hay setval().

También podría tener la función toma un parámetro para el número de veces del ciclo:

CREATE OR REPLACE FUNCTION foo(loopcnt int) RETURNS SETOF INT AS $$ 
DECLARE 
    seqval int;  
    x int; 
BEGIN 
x := 0; 
WHILE x < loopcnt LOOP 
    SELECT into seqval nextval('f_id_seq'); 
    RETURN NEXT seqval;x := x+1; 
END LOOP; 
RETURN; 
END; 
$$ LANGUAGE plpgsql STRICT; 
+0

Tenga en cuenta que debido al uso de 'setof', debe llamarlo como una tabla: 'select * from foo (500);' – TML

0

A menos que realmente desee que se devuelvan tres filas, establecería la secuencia en 'INCREMENT BY BY' para cada selección. Entonces puede agregar 1 y 2 al resultado que tiene sus tres números de secuencia.

He intentado agregar un enlace a los documentos de postgresql, pero evidentemente no tengo permiso para publicar enlaces.

+0

Apreciado, pero las caídas señaladas en el enlace de Ants Aasma son demasiado pronunciadas para que yo pueda modificar el incremento ... y la cantidad de identificadores que necesito varía, por lo que prefiero obtener todos los identificadores individualmente (lo que hace que el código que utiliza los ids son más simples de todos modos). –

11

Hay un gran artículo sobre este problema exacto: "getting multiple values from sequences".

Si el rendimiento no es un problema, por ejemplo cuando se utilizan los valores de secuencia empequeñece el tiempo utilizado para obtenerlos o n es pequeño, entonces el SELECT nextval ('SEQ') desde generate_series (1, n) enfoque es el más simple y más apropiado.

Pero cuando la preparación de datos para mayor carga el último enfoque del artículo de incrementar la secuencia por n desde dentro de una cerradura es apropiada.

+0

Curiosamente, ese artículo parece haber sido escrito por la persona que escribió la respuesta que acepté :-) Independientemente, la serie_generada se ajusta a mis necesidades porque la cantidad de identificadores que necesito es de alrededor de una docena. En un caso muy raro, tal vez 100 ... entonces las caídas de la otra solución presentada en el artículo son demasiado pronunciadas para mi uso. +1 para un buen enlace! –

Cuestiones relacionadas