Czy istnieje sposób wstawienia wielu wierszy do tabeli z wartościami domyślnymi dla wszystkich kolumn?


14

Mogę wstawić wiele wierszy do tabeli z wartościami domyślnymi dla wszystkich kolumn w sposób 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;$$;

Czy istnieje sposób, aby zrobić to samo z pojedynczą instrukcją SQL?


Obszerna odpowiedź na ściśle powiązane pytanie na stronie SO: stackoverflow.com/questions/23794405/...
Erwin Brandstetter

Odpowiedzi:


8

Używanie generate_series()i ctes. Testowane w 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

W przypadku, gdy jest tylko jedna kolumna i jest to serial, nie widzę sposobu na użycie default. Korzystanie z generator_series jest proste:

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

  • Jeśli istnieją inne, bardziej „specyficzne” wartości domyślne, takie jak funkcja UUID lub niestandardowa clock_timestamp(), instrukcja będzie musiała zostać odpowiednio dostosowana, podobnie jak przypadek szeregowy.

Jeśli kluczem podstawowym jest „nie pierwsza” kolumna, w tym przykładzie, jeśli ijest zdefiniowana jako pierwsza, możesz w pewnym stopniu poradzić sobie z prostszą wersją, taką jak, INSERT INTO t SELECT * FROM generate_series(1, 10)która zasadniczo przypisuje pierwszą kolumnę i daje wartości domyślne dla całej reszty, chociaż ja nie mogłem wymyślić żadnych innych łatwych sposobów. Jeśli jest to jednorazowo, możesz to zrobić najpierw za pomocą klucza podstawowego, na przykład generując serię wartości, których „prawdopodobnie nigdy nie użyjesz ponownie”, INSERT INTO t SELECT * FROM generate_series(1000000, 1000000+10)a następnie ręcznie zmieniając liczby.
rogerdpack

Kiedy uruchomiłem go w SQL Fiddle, pierwsze zapytanie nie wstawiło żadnych wierszy do tabeli t. Czy nie używałem poprawnie SQL Fiddle?
Derek Mahar

Teraz rozumiem, co zrobiłem źle. SQL Fiddle traktuje każde wykonanie jak transakcję, którą wycofuje po zakończeniu. W związku z tym, aby zobaczyć wiersze w tabeli, musiałem wykonać select * from tpo instrukcji CTE.
Derek Mahar

Nie, to też nie działało.
Derek Mahar

1
@DerekMahar SQLfiddle musi być zepsuty. Edytowałem link w mojej odpowiedzi na rextester.com.
ypercubeᵀᴹ
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.