¿Hay alguna manera de insertar varias filas en una tabla con valores predeterminados para todas las columnas?

14

Puedo insertar varias filas en una tabla con valores predeterminados para todas las columnas de la manera RBAR :

create table course(course_id serial primary key);

do $$
begin
  for i in 1..100000 loop
    insert into course default values;
  end loop;
end;$$;

¿Hay alguna manera de hacer lo mismo con una sola instrucción SQL?

Jack dice que intente topanswers.xyz
fuente
Amplia respuesta a una pregunta estrechamente relacionada sobre SO: stackoverflow.com/questions/23794405/…
Erwin Brandstetter

Respuestas:

8

Utilizando generate_series()y ctes. Probado en rextester.com :

create table t
( tid serial primary key,
  i int default 0,
  name text default 'Jack'
) ;


with ins as
  (insert into t (i, name)               -- all the columns except any serial
   values (default, default)
   returning i, name
  )
insert into t 
  (i, name)
select 
  ins.i, ins.name
from 
  ins cross join generate_series(1, 9);  -- one less than you need

Para el caso cuando solo hay una columna y es una serial, no veo forma de usar el default. El uso de generate_series es sencillo:

insert into course
  (course_id)
select
  nextval('course_course_id_seq')
from
  generate_series(1, 10);

  • Si hay otros valores predeterminados más "peculiares", como una función UUID o la no estándar clock_timestamp(), la declaración deberá ajustarse en consecuencia, como el caso en serie.
ypercubeᵀᴹ
fuente
Si la clave principal es "no la primera" columna definida, en este ejemplo, si ise define primero, entonces puede obtener una versión más simple como la INSERT INTO t SELECT * FROM generate_series(1, 10)que básicamente se asigna a la primera columna y proporciona valores predeterminados a todo el resto, aunque yo No podría encontrar otras formas fáciles. Si es solo una vez, también podría hacerlo primero con la clave primaria, por ejemplo, al generar una serie de valores que "probablemente nunca reutilizará", por ejemplo: INSERT INTO t SELECT * FROM generate_series(1000000, 1000000+10)luego, cambie los números manualmente después de eso.
rogerdpack
Cuando lo ejecuté en SQL Fiddle, la primera consulta no insertó ninguna fila en la tabla t. ¿No utilicé SQL Fiddle correctamente?
Derek Mahar
Ahora entiendo lo que hice mal. SQL Fiddle trata cada ejecución como una transacción que revierte cuando termina. En consecuencia, para ver las filas en la tabla, tuve que ejecutar select * from tdespués de la declaración CTE.
Derek Mahar
No, eso tampoco funcionó.
Derek Mahar
1
@DerekMahar SQLfiddle debe estar roto. He editado el enlace en mi respuesta a rextester.com.
ypercubeᵀᴹ