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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 02.08.2011, 11:19   #1
WoodHead
Пользователь
 
Регистрация: 12.01.2011
Сообщений: 16
По умолчанию Копирование записи с заменой значений некоторых полей

Прошу помочь, уважаемые гуру. Самостоятельно справиться никак не получается.

Постановка задачи.
Delphi+Access+ADO.
Например, в базе данных есть поля ‘Фамилия’, ‘Имя’, ‘Адрес’. Проживающие (несколько человек) по одному из адресов переехали в другой город, и мне нужно оставить существующие записи с адресом, а также добавить новые записи с новым адресом (тогда в базе будет список всех адресов, по которым проживали эти люди).

Схема решения.
Вот схема кода с выделенным непонятным местом. Надеюсь на вашу помощь.

Код:
procedure TForm1.FormCreate(Sender: TObject);
begin
  ADOTable1.Active:=False;
  ADOTable1.TableName:=’AddressBook’;
  ADOTable1.Active:=True;
  ADOTable1.First;
  While not ADOTable1.eof do
  begin
    if (ADOTable1.fieldbyname(‘Address’).AsString = ‘Москва…’) then
    begin

    …………………// вот здесь непонятно, что делать
 
    ADOTable1.Post;
    end;
  ADOTable1.Next;//переходим на следующую запись
  end;
end;
Например, если вставить на "непонятное" место (см. выше):
Код:
ADOTable1.Insert;
ADOTable1.fieldbyname(‘Surname’).AsString:= varSurname;
ADOTable1.fieldbyname(‘Name’).AsString:= varName;
ADOTable1.fieldbyname(‘Address’).AsString:= ‘Омск…’;
то добавление строки с заменой будет ровно одно, т.к. курсор переходит на новую строку, которая добавляется в конец таблицы (неважно, использовать метод Append или Insert), а это значит немедленный выход по условию "While not ADOTable1.eof do".

Есть дурацкая идея копировать данные, удовлетворяющие условию, в какую-нибудь промежуточную таблицу, а потом уже вставлять в исходную базу. Но это решение, по-моему, переплюнет "индокод" и "быдлокод" вместе взятые. Уже всю голову сломал, никак не могу найти решение.

Последний раз редактировалось WoodHead; 02.08.2011 в 11:24.
WoodHead вне форума Ответить с цитированием
Старый 02.08.2011, 11:35   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Причем здесь быдлокод? Примерно так и прийдется сделать.
Вариант 1. Пробежаться по таблице, выбирая в массив в памяти инфу для вставки. Потом из памяти добавить записи в ADOTable
Вариант2. Сканируя ADOTable создавать инсерты в ADOQuery, по концу запустить ADOQuery.ExecSQL
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 02.08.2011, 11:50   #3
WoodHead
Пользователь
 
Регистрация: 12.01.2011
Сообщений: 16
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
...Вариант2. Сканируя ADOTable создавать инсерты в ADOQuery, по концу запустить ADOQuery.ExecSQL
Вот так?

Код:
procedure TForm1.FormCreate(Sender: TObject);
begin
  ADOTable1.Active:=False;
  ADOTable1.TableName:=’AddressBook’;
  ADOQuery1.SQL.Clear;
  ADOTable1.Active:=True;
  ADOTable1.First;
  While not ADOTable1.eof do
  begin
    if (ADOTable1.fieldbyname(‘Address’).AsString = ‘Москва…’) then
     ADOQuery1.SQL.Add('INSERT INTO AddressBook(Address) VALUES(''Омск...'')'); 

  ADOTable1.Next;//переходим на следующую запись
  end;
  ADOQuery1.ExecSQL;
end;
WoodHead вне форума Ответить с цитированием
Старый 02.08.2011, 11:53   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Примерно, только что-то в Insert-е маловато полей вставляется. В #1 вы побольше данных в запись помещали. По Access не могу уверенно сказать, скушает ли он одновременно несколько инсертов
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 02.08.2011, 12:14   #5
WoodHead
Пользователь
 
Регистрация: 12.01.2011
Сообщений: 16
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
Примерно, только что-то в Insert-е маловато полей вставляется. В #1 вы побольше данных в запись помещали.
Да, поторопился. Исправил.
Код:
procedure TForm1.FormCreate(Sender: TObject);
begin
  ADOTable1.Active:=False;
  ADOTable1.TableName:=’AddressBook’;
  ADOQuery1.SQL.Clear;
  ADOTable1.Active:=True;
  ADOTable1.First;
  While not ADOTable1.eof do
  begin
    if (ADOTable1.fieldbyname(‘Address’).AsString = ‘Москва…’) then
     ADOQuery1.SQL.Add('INSERT INTO AddressBook(Surname,Name,Address) VALUES(ADOTable1.fieldbyname(‘Surname’).AsString,ADOTable1.fieldbyname(‘Name’).AsString,''Омск...'')'); 

  ADOTable1.Next;//переходим на следующую запись
  end;
  ADOQuery1.ExecSQL;
end;
Попробую, спасибо.
Цитата:
Сообщение от Аватар Посмотреть сообщение
По Access не могу уверенно сказать, скушает ли он одновременно несколько инсертов
Несколько сотен инсертов. Пример выдуман, реальная задача посложней. Но механизм тот же.

Последний раз редактировалось WoodHead; 02.08.2011 в 12:16.
WoodHead вне форума Ответить с цитированием
Старый 02.08.2011, 12:19   #6
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Код:
ADOQuery1.SQL.Add(Format('INSERT INTO AddressBook(Surname,Name,Address) VALUES(''%s'',''%s'',''Омск...'')',
  [ADOTable1.fieldbyname(‘Surname’).AsString,ADOTable1.fieldbyname(‘Name’).AsString]));
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 02.08.2011, 14:42   #7
WoodHead
Пользователь
 
Регистрация: 12.01.2011
Сообщений: 16
По умолчанию

Выдает ошибку

Код:
"Пропущен символ (;) в конце инструкции SQL."
Несколько раз проверил все до запятой, нигде ничего не пропустил. Компилируется все нормально, а вот при запуске проекта выдает ошибку.

В связи с этим несколько вопросов.

1. На форме у меня присутствуют ADOTable1, ADOQuery1, ADOConnection1 и DataSource1.
- в DataSource1 в свойстве Dataset стоит ADOTable1;
- в ADOQuery1 в свойстве DataSource стоит DataSource1;
- в ADOTable1 и в ADOQuery1 в свойстве connection содержится ADOConnection1.
Не пропустил ли я чего? Могут ли одновременно работать компоненты ADOTable1 и ADOQuery1.

2. В таблице полей больше, чем 3, но я вывел только 3 поля (как в вышеозначенном примере). Может быть это повлияло на появление ошибки? Обязательно ли заполнять данными все поля, чтобы такой ошибки не возникало?

Последний раз редактировалось WoodHead; 02.08.2011 в 14:44.
WoodHead вне форума Ответить с цитированием
Старый 02.08.2011, 14:54   #8
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Цитата:
Пропущен символ ( в конце инструкции SQL.
Видимо Access требует разделение инструкций точкой с запятой при множественной вставке. Попробуйте поставить ; в конце каждого Insert-а
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 02.08.2011, 15:18   #9
WoodHead
Пользователь
 
Регистрация: 12.01.2011
Сообщений: 16
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
Видимо Access требует разделение инструкций точкой с запятой при множественной вставке. Попробуйте поставить ; в конце каждого Insert-а
Да, вопрос только - где?

Здесь
Код:
ADOQuery1.SQL.Add(Format('INSERT INTO AddressBook(Surname,Name,Address) VALUES(''%s'',''%s'',''Омск...'');', [ADOTable1.fieldbyname(‘Surname’).AsString,ADOTable1.fieldbyname(‘Name’).AsString]));
ругается "Обнаружены символы за пределами инструкции SQL."

А если здесь
Код:
ADOQuery1.SQL.Add(Format('INSERT INTO AddressBook(Surname,Name,Address); VALUES(''%s'',''%s'',''Омск...'')', [ADOTable1.fieldbyname(‘Surname’).AsString,ADOTable1.fieldbyname(‘Name’).AsString]));
то "Ошибка синтаксиса в инструкции INSERT INTO."
WoodHead вне форума Ответить с цитированием
Старый 02.08.2011, 15:30   #10
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Ну тогда каждый Insert обрабатывать по полному циклу (Clear, Add, ExecSQL) или первый вариант
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Поиск файла и копирование с заменой tarakan1983 Общие вопросы Delphi 11 29.04.2010 15:14
Прога на подсчет значений функции: не разрешает в некоторых местах использование jo!! Masha)) Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 4 20.11.2009 20:24
копирование всех полей класса Juffin Общие вопросы Delphi 1 19.05.2009 19:16
Сохранение значений вычисляемых полей gimbomba БД в Delphi 6 21.02.2009 19:19