Чи є спосіб вставити кілька рядків у таблицю із значеннями за замовчуванням для всіх стовпців?


14

Я можу вставити кілька рядків у таблицю із значеннями за замовчуванням для всіх стовпців способом 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;$$;

Чи існує спосіб зробити те ж саме з одним оператором SQL?


Обширна відповідь на тісно пов’язане питання щодо SO: stackoverflow.com/questions/23794405/…
Ервін Брандстеттер

Відповіді:


8

Використання generate_series()та ctes. Тестовано на 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

У випадку, коли є лише один стовпець, і він є serial, я не бачу способу його використовувати default. Використання generator_series прямо:

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

  • Якщо існують інші, більш "своєрідні" значення за замовчуванням, як-от функція UUID або нестандартна clock_timestamp(), оператор повинен буде бути скоригований відповідно, як і серійний випадок.

Якщо основним ключем є "не перший" стовпець, визначений у цьому прикладі, якщо iвін визначений спочатку, то ви можете дещо перейти через більш просту версію, на зразок INSERT INTO t SELECT * FROM generate_series(1, 10)якої в основному присвоюється першому стовпцю та дає за замовчуванням всім іншим, хоча я не вдалося розібратися з іншими простими способами. Якщо це лише один вимикач, то ви також можете спершу це зробити з первинним ключем, наприклад, створивши ряд значень, які ви "ймовірно ніколи не повторно використаєте", наприклад: INSERT INTO t SELECT * FROM generate_series(1000000, 1000000+10)потім змінивши цифри вручну після цього.
rogerdpack

Коли я запустив його в SQL Fiddle, перший запит не вставив жодних рядків у таблицю t. Чи правильно я не використовував SQL Fiddle?
Дерек Махар

Я зараз розумію, що я зробив не так. SQL Fiddle розглядає кожне виконання, як транзакцію, яку він відновлює, коли виконано. Отже, щоб побачити рядки в таблиці, мені довелося виконати select * from tпісля оператора CTE.
Дерек Махар

Ні, це теж не вийшло.
Дерек Махар

1
@DerekMahar SQLfiddle має бути порушено. Я відредагував посилання у своїй відповіді на rextester.com.
ypercubeᵀᴹ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.