Задать вопрос
@DiIce

Как вставить в постгресе запись сразу в две таблицы, так, чтобы во второй было поле с BIGSERIAL из первой?

Суть:
есть база POSTGRESQL 9.3 и есть две таблицы, banners и keywords.
Обе имеют первое поле id BIGSERIAL, и далее набор полей по вкусу
так как banner может быть сделан для нескольких keyword, решено было хранить в таблице keywords поле banner_id, которое должно в себе содержать поле id из таблицы banners
и в принципе я не парился бы, если бы не было нужды вставить за раз 500 тыс баннеров и миллион ключевиков, и делать это регулярно.
посему ищу максимально эффективный способ вставить в запись в обе таблицы сразу. Условно говоря, чтобы одним запросом часть данных вставлялась в banners, вторая часть - в keywords, причем в keywords в поле banner_id вставлялось значение поля id свежевставленной записи из banners.
  • Вопрос задан
  • 445 просмотров
Подписаться 1 Оценить Комментировать
Решения вопроса 1
dimonchik2013
@dimonchik2013
non progredi est regredi
ваш запрос из серии "как получить last insert ID одновременно в двух таблицах"
одним красивым запросом без INSERT ... SELECT перед этим сделать ничего нельзя

но есть триггеры

вставляете в одну таблицу все данные, триггер на AFTER INSERT - копируете часть в другую, из первой удаляете (UPDATE) или в конце или триггером из второй таблицы (не уверен что будет работать, но должно)

пример триггера
stackoverflow.com/questions/12343984/insert-trigge...
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@kshvakov
вообще для "кучи" данных лучше использовать COPY www.postgresql.org/docs/current/static/sql-copy.html

а чем вас такой вариант смущает ?

create table banners(banner_id serial primary key, value text);
create table keywords(keyword_id serial primary key, banner_id int references banners);


do $$
	declare 
		_banner_id int;
		i int;
	begin


	FOR i IN 1..10 LOOP 
	
		INSERT INTO banners (value) VALUES ('My banner ' || i) RETURNING banners.banner_id INTO _banner_id;
		
		FOR i IN 1..100 LOOP 
		
			INSERT INTO keywords(banner_id) VALUES (_banner_id);
		END LOOP;
	END LOOP;
	

	end;
$$;
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы