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

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

Вернуться   Форум программистов > Delphi программирование > Компоненты Delphi
Регистрация

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

Купить рекламу на форуме 15-35 тыс рублей в месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.08.2022, 15:27   #1
Explosion
Пользователь
 
Регистрация: 08.11.2008
Сообщений: 50
По умолчанию Dataset. Из Select сделать Insert.

Здравствуйте.

Delphi: XE2
Dataset: компонент TpFIBDataSet

Dataset выполняет Select. Могу ли я сделать Insert из результата выполненного Select, не используя дополнительный Dataset?
Explosion вне форума Ответить с цитированием
Старый 24.08.2022, 22:33   #2
Viktor61
Пользователь
 
Регистрация: 05.05.2018
Сообщений: 85
По умолчанию

Несколько неконкретно задан вопрос. В общем виде у TpFIBDataSet есть свойство SQLs, включающее InsertSQL, SelectSQL, RefreshSQL, RefreshSQL и DeleteSQL. Как видно из их названий - это различные инструкции для работы с набором на языке SQL. Если TpFIBDataSet простой и может быть изменен, то
Цитата:
Сообщение от Explosion Посмотреть сообщение
сделать Insert
можно. Если не изменяемой, состоящий из нескольких таблиц - как правило - нет. К тому же надо учесть в какой трансакции происходит работа. Где-то так...
Viktor61 вне форума Ответить с цитированием
Старый 25.08.2022, 06:44   #3
Explosion
Пользователь
 
Регистрация: 08.11.2008
Сообщений: 50
По умолчанию

А вот подскажите как это будет выглядеть кодом?

Мне интересно, если я заполню InsertSQL и заполню SelectSQL, а потом выполню датасет командой Dataset.Open. Какой из запросов выполнится Insert или Select? Или они как-то последовательно друг за другом?

И вопрос: допустим в SelectSQL текст "select * from таблица", как сделать так, чтобы можно было результат уже готового запроса-Селекта заИнсёртать в другую таблицу? Можно сделать с помощью конструкции Insert...Select, но в Инсёрте селект повторно выполнится, а ведь у нас уже имеется выполненный Select. Можно пробегаться курсором по строчкам выполненного селекта и для каждой строчки делать отдельный Инсерт, но если строчек будет 10000, то будет 10000 Инсёртов. Понимаю, что способ не один, но вот посоветуйте как это делают опытные программисты?
Explosion вне форума Ответить с цитированием
Старый 25.08.2022, 21:54   #4
Viktor61
Пользователь
 
Регистрация: 05.05.2018
Сообщений: 85
По умолчанию

Цитата:
Сообщение от Explosion Посмотреть сообщение
Можно пробегаться курсором по строчкам выполненного селекта и для каждой строчки делать отдельный Инсерт
- крайне порочный подход. "Бегать" по строчкам не надо! Принцип SQL - это работа СРАЗУ с множеством строк (или с одной строчкой, если есть только одна строка в этом множестве; или ни с одной). Главное - в это множество включаются только строки согласно какому-то условию - Where .... и т.д.
Viktor61 вне форума Ответить с цитированием
Старый 26.08.2022, 08:27   #5
Explosion
Пользователь
 
Регистрация: 08.11.2008
Сообщений: 50
По умолчанию

Viktor61, вы не могли бы написать кодом как можно вставить множество строк?

Например, пусть у меня не SQL-запрос, а какой-нибудь Excel с 2 строчками и 3 колонками: Фамилия, Имя, Отчество. Циклом пробегаюсь по 2-м строчкам. В первый раз пробегаюсь, получил из Excel'а фамилию, имя, отчество. Теперь у меня есть параметры для вставки и по логике мне нужно текущее ФИО Инсертнуть в таблицу. Потом второй раз пробегаюсь и уже вытаскиваю новые ФИО для новой вставки в таблицу, обновляю параметры в соответствии со значениями новых ФИО и снова делаю Инсерт.
Или как-то можно сначала пробежаться по Excel'ю, накопить стэк/массив данных, а потом разом их вставить? Если да, то увидеть бы код.

Последний раз редактировалось Explosion; 26.08.2022 в 08:42.
Explosion вне форума Ответить с цитированием
Старый 26.08.2022, 15:09   #6
Viktor61
Пользователь
 
Регистрация: 05.05.2018
Сообщений: 85
По умолчанию

Ув. Explosion! TpFIBDataSet - это не про Excel. Он заточен именно для работы c Interbase/firebird.
Зачем брать крутую тачку и кататься на поселковых дорогах? Лишнее это - используйте подходящий инструмент (ШУТКА!).
Если уж, предполагаю, Вам, "в наследство" досталась БД с TpFIBDataSet, то каким-либо образом получайте данные для вставки,
создавайте Хранимую процедуру ставки на сервере Interbase/firebird.
Хотите код - их есть у меня
Код:
--Всё это надо выполнить на сервере Interbase/firebird. Например, в IBExperte (редактор скриптов).

CREATE GENERATOR gen_FIO; --Создание генератора 

COMMIT WORK;

SET GENERATOR gen_FIO TO 1; --Установка генератора-счетчика в 1

COMMIT WORK;

--создание таблицы CODF-первичный ключ; FAM, IMIA, OTCH - поля строк длиной до 20 символов (не могут быть пустыми). 
CREATE TABLE FAMIL (
    CODF  INTEGER NOT NULL,
	FAM VARCHAR(20) NOT NULL,
    IMIA VARCHAR(20) NOT NULL,
	OTCH VARCHAR(20) NOT NULL
);

COMMIT WORK;

--Тригер - автовставки первичного ключа - аналог автоинкрементного поля
CREATE OR ALTER trigger tbiu_FIO for FAMIL
active before insert or update position 0
AS
  BEGIN
   IF (NEW.CODF IS NULL) THEN NEW.CODF = GEN_ID(gen_FIO, 1);
  END
  
COMMIT WORK;

--Собственно процедура вставки 
create or alter procedure PRC_SETFIO (
    V_FAM VARCHAR(20),
    V_IMIA VARCHAR(20),
	V_OTCH VARCHAR(20)
    )
as
begin
  INSERT INTO FAMIL(CODF, FAM, IMIA, OTCH)
   VALUES (null, :V_FAM, :V_IMIA, :V_OTCH);
end

COMMIT WORK;
Viktor61 вне форума Ответить с цитированием
Старый 26.08.2022, 15:23   #7
Viktor61
Пользователь
 
Регистрация: 05.05.2018
Сообщений: 85
По умолчанию

В программе
Код:
Разместить pFIBDatabase: TpFIBDatabase,
           pFIBTransaction: TpFIBTransaction;
		   pFIBStoredProc: TpFIBStoredProc,
	с палитры FIBPlus. И настроить взаимодействие между ними.
Я переименовал pFIBStoredProc в pFIBStoredProcInsertApdat: TpFIBStoredProc;

const 
rstStrError = 'ОШИБКА!';
sSQL = 'EXECUTE PROCEDURE PRC_SETFIO (:FAM, :IMYA, :OTCH)';


function InsApdDataBD_str(sSQL,  sValue, sValue1, sValue2: string):  boolean;
begin
  result := false;
  with pFIBStoredProcInsertApdat do
  begin
    SQL.Clear;
    SQL.Append(sSQL);
    Params[0].AsString := sValue;
    Params[1].AsString := sValue1;
	Params[2].AsString := sValue2;
    Prepare;
  end;
  try
    pFIBStoredProcInsertApdat.ExecProc;
  except
    on E: Exception do
    begin
      Application.MessageBox('Не удается ввести данные(1)!', PChar(rstStrError), MB_OK + MB_ICONSTOP);
      Exit;
    end;
  end;

  try
    pFIBStoredProcInsertApdat.Transaction.Commit;
  except
    on E: Exception do
    begin
      Application.MessageBox('Не удается ввести данные(2)!', PChar(rstStrError), MB_OK + MB_ICONSTOP);
      pFIBStoredProcInsertApdat.Transaction.Rollback;
      Exit;
    end;
  end;
  result := true;
end;


Вызов в программе 
 if InsApdDataBD_str(sSQL, ФАМ, ИМЯ, ОТЧ) = false then  ShowMessage('Ошибка - Не вводится ФИО!');
Viktor61 вне форума Ответить с цитированием
Старый 29.08.2022, 06:32   #8
Explosion
Пользователь
 
Регистрация: 08.11.2008
Сообщений: 50
По умолчанию

Цитата:
Сообщение от Viktor61 Посмотреть сообщение
"Бегать" по строчкам не надо!
Viktor61, хранимая процедура будет исполняться столько раз сколько будет строк с ФИО в таблице. И в итоге бегать по строчкам всё равно придётся.
Explosion вне форума Ответить с цитированием
Ответ
Опции темы Поиск в этой теме
Поиск в этой теме:

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
dataset not in edit or insert mode Анжеликааа Общие вопросы Delphi 7 05.01.2015 22:59
ошибка dataset not in edit or insert mode Chicharrr Помощь студентам 2 06.06.2012 18:34
Ошибка dataset not in edit or insert mode. thebrownie Общие вопросы Delphi 3 12.02.2012 18:47
dataset is not edit or insert mode Drugnir Общие вопросы C/C++ 1 26.09.2011 09:56