Изменить размер поля или его тип
Материал из DRKB
Изменить размер поля или его тип[править | править код]
Единственный способ изменить размер поля или его тип - использовать DBIDoRestructure. Вот простой пример, который может вам помочь в этом:
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;
Примечание Vit: На счёт "Единственный способ" - этот товарищ несколько погорячился. Все базы данных поддерживают SQL запрос вида
ALTER TABLE ...
Конкретный формат надо выяснить в справочнике по используемой базе данных, так как он немного различается для разных серверов, но указанный запрос весьма гибок, и применим не только с BDE, но и с другими системами доступа и с любыми базами данных.
Source: Взято с http://delphiworld.narod.ru
ID: 02615