C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
LoadFromFile, ClientDataSet
Лена
Отправлено: 25.09.2006, 17:32


Мастер участка

Группа: Участник
Сообщений: 501



Как сделать следующее:
Пользовать открыл файл *.xml в ClientDataSet, теперь надо содержимым этого файла заменить содержимое реальной таблицы из базы данных связанной с ClientDataSet.
Так не правильно:
CODE

void __fastcall TForm1::ButtonOpenClick(TObject *Sender)
{
  if(OpenDialog1->Execute())
   {
    DataModule2->ClientDataSetKey->LoadFromFile(OpenDialog1->FileName);
    if (Application->MessageBox("Заменить этой открываемой таблицей соответствующую ей таблицу в базе данных?",
        "Произвести замену?", MB_YESNO + MB_ICONQUESTION) == IDYES) {

       //очищаю старое содежимое в базе данных
        DataModule2->ADOQueryKey->Active = false;
        DataModule2->ADOQueryKey->SQL->Clear();
        DataModule2->ADOQueryKey->SQL->Add("delete FROM keys");
        DataModule2->ADOQueryKey->Active = true;
        DataModule2->ClientDataSetKey->ApplyUpdates(-1); //исключение
    }
    else {

      return;
    }

   }
}


ОШИБКА: Command text does not return a result set! sad.gif
Лена
Отправлено: 26.09.2006, 09:58


Мастер участка

Группа: Участник
Сообщений: 501



Пробую так:

CODE

void __fastcall TForm1::ButtonOpenClick(TObject *Sender)
{
if(OpenDialog1->Execute())
{
DataModule2->ClientDataSetKey->LoadFromFile(OpenDialog1->FileName);
if (Application->MessageBox("Заменить этой открываемой таблицей соответствующую ей таблицу в базе данных?",
"Произвести замену?", MB_YESNO + MB_ICONQUESTION) == IDYES) {
int ErrCount = 0;
      //DataSetProviderKey это провайдер
DataModule2->DataSetProviderKey->ApplyUpdates(DataModule2->ClientDataSetKey->Data, -1, ErrCount);


}
else {

return;
}

}


Загружаю файл, жму "ОК". Во вновь загруженные в грид данные добавляю еще одну строку с данными. Закрываю приложение. Открываю его вновь. В гриде находиться только строка, которую я добавила, а всех данных из .xml файла снова нет в гриде. Не происходит замена и пересылка данных после LoadFromFile в базу. Как подправить код? rolleyes.gif

Отредактировано Лена — 26.09.2006, 09:58
olegenty
Отправлено: 26.09.2006, 16:00


Ветеран

Группа: Модератор
Сообщений: 2412



ты что-то путаешь. вот что именно: загрузка данных из файла НЕ ГЕНЕРИРУЕТ ИНСТРУКЦИЙ по изменению/добавлению/удалению данных из таблицы БД. ты можешь загрузить данные в "фоновый набор", пройдя по нему выполнить Edit()/Insert()/Delete() в основном наборе, затем подтвердить изменения основного набора. либо "дропнуть" таблицу БД и превратить внешний файл в инструкцию INSERT.
Лена
Отправлено: 26.09.2006, 16:34


Мастер участка

Группа: Участник
Сообщений: 501



>загрузка данных из файла НЕ ГЕНЕРИРУЕТ ИНСТРУКЦИЙ по изменению/добавлению/удалению данных из таблицы

Вот я и пытаюсь написать эти инструкции. Хочу после загрзки данных из файла, удалить все данные из таблицы базы данных и загрузить туда те, что получила из файла. smile.gif
olegenty
Отправлено: 27.09.2006, 07:15


Ветеран

Группа: Модератор
Сообщений: 2412



Лен, ты невнимательно читала мой предыдущий пост. Ты не пытаешься, а даже наоборот — ничего не делаешь (грузишь данные и думаешь, что от тебя больше ничего не требуется). Думаешь, что всё будет по щучьему велению? (для этого, как минимум, нужна говорящая щука)
Admin
Отправлено: 27.09.2006, 13:45


Владимир

Группа: Администратор
Сообщений: 1190



Возможно, примерно такой вариант:

CODE

//---------------------------------------------------------------------------
// читаем из файла сохраненные ранее данные
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ADODataSet1->Close();
ADOConnection1->Connected = false;
ADODataSet1->LoadFromFile(L"country.adtg");
}
//---------------------------------------------------------------------------


CODE

// вставляем данные в таблицу
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
AnsiString sql;
ADOConnection1->Connected = true;

// предварительно удаляем все записи из таблицы 'country'
ADOCommand1->CommandText = "Delete from country";
ADOCommand1->Execute();

// начинаем вставку из файла (локального кэша)
while(!ADODataSet1->Eof){
ADOQuery1->SQL->Clear();
sql="insert into country values(";
for(int i=0; i<ADODataSet1->FieldCount; i++)
{
switch(ADODataSet1->Fields->Fields[i]->DataType)
{
case ftString, ftWideString: sql=sql+"'"+ADODataSet1->Fields->Fields[i]->AsString+"'"; break;
case ftInteger,ftWord: sql = sql + ADODataSet1->Fields->Fields[i]->AsString; break;
default: sql = sql + ADODataSet1->Fields->Fields[i]->AsString; break;
}
sql = sql + ",";
}

sql.Delete(sql.Length(), 1);
sql = sql+")";
ADOQuery1->SQL->Add(sql);
ADOQuery1->ExecSQL();
ADODataSet1->Next();
}
}
//---------------------------------------------------------------------------
olegenty
Отправлено: 27.09.2006, 14:13


Ветеран

Группа: Модератор
Сообщений: 2412



2 Лена — вот то, что Admin написал, я и имел в виду... (примерно)
Лена
Отправлено: 27.09.2006, 14:24


Мастер участка

Группа: Участник
Сообщений: 501



Большое спасибо за помощь! victory.gif
Теперь понятна реализация таких здач.
Admin
Отправлено: 27.09.2006, 18:59


Владимир

Группа: Администратор
Сообщений: 1190



Не уверен, конечно, что это правильный или хороший способ.

Вполне возможно, что вариант с ADODataSet1->UpdateBatch(arAll);
будет и более удобным для Вас. Он тоже позволяет переносить
изменения из локального файла в базу.

Вернуться в Работа с базами данных в C++Builder