| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Базы данных и репортинг > Упаковка индексированной таблицы Paradox |
| Автор: AlexanderI 10.2.2005, 21:23 |
| Всем привет. У меня в программе две реляционные таблицы (Paradox 7). Т.е. по активации поля в первой таблице, показываются соответствующие данные во второй. Связаны эти таблицы по полям "sta" (для первой) и "stb" (для второй). Соответственно, чтобы осуществилась такая реляционная связь, вторая таблица проиндексированна (secondary index) по полю "stb". Индекс этот назван ind_std. Связь этих таблиц задана на этапе проектирования, т.е. не программно. Мне нужно добавить новую запись в таблицу №2. Делаю это так: //Сперва удаляю связь, т.к. без этого программа ругается на индексацию (связь). Table2.MasterFields := ''; Table2.IndexName := ''; //А потом добавляю новую запись Table2.Insert; Table2.FieldByName('stb').AsInteger := strtoint(Edit1.Text); Table2.FieldByName('NNO').AsInteger := strtoint(Edit2.Text); Table2.FieldByName('NSL').AsString := 'Edit3.Text'; Данные вроде-как добавились, потом я востанавливаю связь двух таблиц: Table2.IndexName:= 'ind_std'; Table2.MasterFields := 'sta'; И программа начинает ругаться "Index is out of date. Index ind_std". Если выйти из программы и зайти снова, то быдет вылазить таже самая ошибка. Я так понимаю что таблицу№2 теперь нужно сжать, т.е. сделать ей Table Pack. Отсюда вопрос: Как ей сделать этот Table Pack программно ? Если делать это руками, то через Database Desktop всё работает. Т.е. открывается база и просто ставится галочка напротив Pack Table и всё. Сжимал таким способом, но он мне ничего хорошего не дал. Procedure TfmMain.PackTable(tLog:TTable); var TblDesc: CRTblDesc; // rslt: DBIResult; Dir: string; //имеется в виду huge string т.е. {$H+} hDb: hDbiDb; begin if tLog.Active then tLog.Active := False; //деактивиpуем TTable if not tLog.Exclusive then tLog.Exclusive:=True; SetLength(Dir, dbiMaxNameLen + 1); DbiGetDirectory(tLog.DBHandle, False, PChar(Dir)); SetLength(Dir, StrLen(PChar(Dir))); DbiOpenDatabase(nil, nil, dbiReadWrite, dbiOpenExcl, nil, 0, nil, nil, hDb); DbiSetDirectory(hDb, PChar(Dir)); FillChar(TblDesc, sizeof(CRTblDesc), 0); StrPCopy(TblDesc.szTblName, vDBPath+tLog.TableName); StrCopy(TblDesc.szTblType, szParadox);//BTW тут может и szDBase стоять TblDesc.bPack := TRUE; DbiDoRestructure(hDb, 1, @TblDesc, nil, nil, nil, False); DbiCloseDatabase(hDb); end; Делаю я это на Delphi_6. Может кто знает ответ ? |
| Автор: Akella 11.2.2005, 10:24 | ||
| Во первых упаковка здесь не поможет. Делай так. Берем два комплекта компонент (TTable, TDataSource, TDBGrid) и одну компоненту TDataBase. В обеих таблицах должны быть primary-индексы, в Detail-таблице Secondary-индекс. Связываем все цепочки, устанавливаем имена таблиц, все активируем. Надеюсь не составит труда. 1.TDataBase+MasterTable+MasterSource+TDBGrid. 2. TDataBase+DetailTable+DetailSource+TDBGrid. далее связваем цепочку Master-Detail DetailTable.MasterSource := MasterSource (источник данных Master-таблицы) В свойстве MasterField компоненты DetailTable щелкаем по кнопочке с тремя точечками. Появляется окошечко. Вверху, из выпадающего списка, выбираем Secondary-индекс детальной таблицы. Чуть ниже и слева выбираем поле (входящее в Primary-индекс) основной таблицы, напротив справа выбираем поле (входящее в Secondary-индекс) детальной таблицы. Посередине нажимаем кнопку Add. Ниже добавяться связка полей. Нажимаешь Ok. Все готово. В DataBaseDesktop`е не рекомендую связывать. Т.к. на програмном уровне уже ничего не сделаешь. Буду вопросы - пишы. Может будет время пример выложу. В случае таких ошибок нужно удалять и заново создавать индексы. С Primary-индексами сложнее. В DataBaseDesktop`е создаешь ещё одно поле Integer, удаляешь старое Autoinc, новое ставишь тип Autoinc и ставишь плюсик (Primary-индекс). Сохраняешь. Если есть связанные данные - связь может потеряться. Добавлено @ 10:32
А где Table2.Post. |
| Автор: AlexanderI 12.2.2005, 14:35 |
| Если честно, я не понял твой способ. Очень бы хотелось посмотреть на твой пример. У меня в таблице нет Автоинкрементных полей. Я вот что подумал, а что если для добавления записи сперва удалить, а потов заново добавить индекс средствами SQL ? Как бедут лучше ? Может мне вообще другим способом это делать ? |