Изменить размер поля или его тип |
Previous Top Next |
Автор: Reinhard Kalinke
Единственный способ изменить размер поля или его тип - использовать DBIDoRestructure. Вот простой пример, который может вам помочь в этом:
Code: |
function BDEStringFieldResize(ATable: TTable; AFieldName: string; ANewSize: integer): boolean; type TRestructStatus = (rsFieldNotFound, rsNothingToDo, rsDoIt); var hDB: hDBIdb; pTableDesc: pCRTblDesc; pFldOp: pCROpType; {фактически это массив array of pCROpType} pFieldDesc: pFldDesc; {фактически это массив array of pFldDesc} CurPrp: CurProps; CSubType: integer; CCbrOption: CBRType; eRestrStatus: TRestructStatus; pErrMess: DBIMsg; i: integer; begin Result := False; eRestrStatus := rsFieldNotFound; AFieldName := UpperCase(AFieldName); pTableDesc := nil; pFieldDesc := nil; pFldOp := nil;
with ATable do try
{убедимся что имеем исключительный доступ и сохраним dbhandle:} if Active and (not Exclusive) then Close; if (not Exclusive) then Exclusive := True; if (not Active) then Open; hDB := DBHandle;
{готовим данные для DBIDoRestructure:} BDECheck(DBIGetCursorProps(Handle, CurPrp)); GetMem(pFieldDesc, CurPrp.iFields * sizeOf(FldDesc)); BDECheck(DBIGetFieldDescs(Handle, pFieldDesc)); GetMem(pFldOp, CurPrp.iFields * sizeOf(CROpType)); FillChar(pFldOp^, CurPrp.iFields * sizeOf(CROpType), 0);
{ищем в цикле (через fielddesc) наше поле:} for i := 1 to CurPrp.iFields do begin {для ввода мы имеем серийные номера вместо Pdox ID, возвращаемых DbiGetFieldDescs:} pFieldDesc^.iFldNum := i; if (Uppercase(StrPas(pFieldDesc^.szName)) = AFieldName) and (pFieldDesc^.iFldType = fldZSTRING) then begin eRestrStatus := rsNothingToDo; if (pFieldDesc^.iUnits1 <> ANewSize) then begin pFieldDesc^.iUnits1 := ANewSize; pFldOp^ := crModify; eRestrStatus := rsDoIt; end; end; inc(pFieldDesc); inc(pFldOp); end; {for}
{"регулируем" массив указателей:} dec(pFieldDesc, CurPrp.iFields); dec(pFldOp, CurPrp.iFields);
{в случае отсутствия операций возбуждаем исключение:} case eRestrStatus of rsNothingToDo: raise Exception.Create('Ничего не сделано'); rsFieldNotFound: raise Exception.Create('Поле не найдено'); end;
GetMem(pTableDesc, sizeOf(CRTblDesc)); FillChar(pTableDesc^, SizeOf(CRTblDesc), 0); StrPCopy(pTableDesc^.szTblName, TableName); {StrPCopy(pTableDesc^.szTblType,szPARADOX); {} pTableDesc^.szTblType := CurPrp.szTableType; pTableDesc^.iFldCount := CurPrp.iFields; pTableDesc^.pecrFldOp := pFldOp; pTableDesc^.pfldDesc := pFieldDesc;
Close;
BDECheck(DbiDoRestructure(hDB, 1, pTableDesc, nil, nil, nil, False));
finally if pTableDesc <> nil then FreeMem(pTableDesc, sizeOf(CRTblDesc)); if pFldOp <> nil then FreeMem(pFldOp, CurPrp.iFields * sizeOf(CROpType)); if pFieldDesc <> nil then FreeMem(pFieldDesc, CurPrp.iFields * sizeOf(FldDesc)); Open; end; {пробуем с table1} Result := True; end; |
©Drkb::02614
Взято с http://delphiworld.narod.ru
Примечание Vit: На счёт "Единственный способ" - этот товарищ несколько погорячился. Все базы данных поддерживают SQL запрос вида
ALTER TABLE...
Конкретный формат надо выяснить в справочнике по используемой базе данных, так как он немного различается для разных серверов, но указанный запрос весьма гибок, и применим не только с BDE, но и с другими системами доступа и с любыми базами данных.
©Drkb::02615