Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.01.2017, 09:41   #1
dualtrey
Пользователь
 
Регистрация: 11.01.2015
Сообщений: 20
Вопрос insert into сразу в несколько таблиц (вложенный insert)

Всем привет, есть три таблицы (см. во вложении). СУБД firebird
На каждую запись главной таблицы могут приходиться несколько записей во второй и третьей.
Задача продублировать записи во всех таблицах где поле YEAR равно, допустим 2016, при этом изменив YEAR на 2017 и присвоив новый ID главной таблицы, MAINID второй и третьей таблице.
Изображения
Тип файла: jpg Tables.jpg (23.4 Кб, 144 просмотров)
dualtrey вне форума Ответить с цитированием
Старый 22.01.2017, 12:26   #2
dualtrey
Пользователь
 
Регистрация: 11.01.2015
Сообщений: 20
По умолчанию

Я немного уточню вопрос.
Задача решена следующим способом:
Код:
while NOT IB.Query1.Eof do begin
IB.Query2.Append;
IB.Query2.Edit;
for i=0 to (IBQuery1.FieldCount-1) do IBQuery2.Field[i].Value := IBQuery1.Field[i].Value;
//Тут точно также запускаем для таблицы Second по другим Query;
//Тут точно также запускаем для таблицы Third по другим Query;
IBQuery1.Next
end;
Все это замечательно отрабатывает, но долго. Решил попробовать конструкцию INSERT INTO.
Для главной таблицы:
Код:
insert into Main (ADRESS, YEAR)
  select ADRESS, YEAR+1
  from Main where YEAR=2016
Выполняет задачу на одной (главной) таблице при количестве записей 180 по 150 полей в каждой за менее чем 1 секунду против 48 секунд перебора IBQuery.EoF

Но вот в SQL запросе связать все три таблицы пока не получается, может есть у кого идеи?
dualtrey вне форума Ответить с цитированием
Старый 22.01.2017, 13:26   #3
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Триггер
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 23.01.2017, 09:21   #4
dualtrey
Пользователь
 
Регистрация: 11.01.2015
Сообщений: 20
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
Триггер
Ну тогда в триггере должно быть что-то типа:
Код:
CREATE OR ALTER TRIGGER ADDYEAR FOR MAIN
ACTIVE AFTER INSERT POSITION 0
AS
begin
  insert into Second (MAINID, NAME, YEAR)
    select NEW.ID, NAME, YEAR+1
    from Second where MAINID = OLD.ID;
end
Но в триггерах на INSERT нельзя читать OLD.columnname.
Как тогда выбрать именно те записи, которые требуется дублировать во второй таблице?
dualtrey вне форума Ответить с цитированием
Старый 23.01.2017, 09:38   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Цитата:
Как тогда выбрать именно те записи, которые требуется дублировать во второй таблице?
Не знаю. Поскольку разобраться в следующей фразе даже с очень большого бодуна не получится
Цитата:
Задача продублировать записи во всех таблицах где поле YEAR равно, допустим 2016, при этом изменив YEAR на 2017 и присвоив новый ID главной таблицы, MAINID второй и третьей таблице.
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 23.01.2017, 10:37   #6
dualtrey
Пользователь
 
Регистрация: 11.01.2015
Сообщений: 20
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
Не знаю. Поскольку разобраться в следующей фразе даже с очень большого бодуна не получится
С этим у меня плохо))
Объясню наглядно что должно получится в результате каких-то действий:

dualtrey вне форума Ответить с цитированием
Старый 23.01.2017, 10:56   #7
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Триггером это не получится, если правильно делать, а не халтурно. Можно SQL процедуру сделать. Можно программно. Firebord позволяет вроде пакетную вставку, т.е. в одном запросе туча Insert-ов. В начале пакета что-то типа EXECUTE BLOCK. Только не в курсе как IB это съест, если получится, то все будет гораздо быстрей
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 23.01.2017 в 10:59.
Аватар вне форума Ответить с цитированием
Старый 23.01.2017, 11:10   #8
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,515
По умолчанию

Цитата:
Но вот в SQL запросе связать все три таблицы пока не получается, может есть у кого идеи?
Цитата:
Ну тогда в триггере должно быть что-то типа:
а это обязательно должен быть тригер?
может можно двумя (или даже ТРЕМЯ) последовательными запросами INSERT
ЕСЛИ надо их можно "объединить" путем вставки в ХП(хранимую процедуру).
Цитата:
Для главной таблицы:
Код:
insert into Main (ADRESS, YEAR)
  select ADRESS, YEAR+1
  from Main where YEAR=2016
для ВТОРОЙ учитывая результат выполнения
Код:
insert into second (mainid, name, year)
select m7.id, second.name, m7.year 
from main as m6
inner join main as m7 on m6.adress =m7.adress and m7.year=m6.year+1 
inner join second on second.mainid =m6.id
where main.year=2016
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 23.01.2017 в 11:13.
evg_m на форуме Ответить с цитированием
Старый 23.01.2017, 12:09   #9
dualtrey
Пользователь
 
Регистрация: 11.01.2015
Сообщений: 20
По умолчанию

Цитата:
а это обязательно должен быть триггер?
Нет, главное ускорить сам процесс.
Цитата:
ЕСЛИ надо их можно "объединить" путем вставки в ХП(хранимую процедуру).
Просто перечислив через ";"?

Цитата:
для ВТОРОЙ учитывая результат выполнения
Код:
(*последняя строка*)
where main.year=2016
На эту строку ругнулся, о том что нет такого поля, поменял на second.year прошло но выполнение процедуры. Но результата я не дождался (если и правильно, то очень долго).
dualtrey вне форума Ответить с цитированием
Старый 23.01.2017, 12:59   #10
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,515
По умолчанию

where main.year=2016 where m6.year=2016
программа — запись алгоритма на языке понятном транслятору
evg_m на форуме Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
INSERT Masafi PHP 7 13.01.2013 12:32
Insert в несколько таблиц одновременно. alexandro704 БД в Delphi 8 29.04.2011 11:42
Несколько insert into в один. MrBobyara SQL, базы данных 2 07.02.2011 18:31
Insert - ? Evgenii БД в Delphi 2 06.07.2009 02:24
как оператором insert вставить данные сразу в две таблицы? furstenberg БД в Delphi 2 18.10.2007 16:39