Текущий архив: 2003.10.13;
Скачать: CL | DM;
ВнизСкудный Local SQL - как изменить структуру таблицы Paradox Найти похожие ветки
← →
Skalp (2003-09-23 23:58) [0]Доброе время суток! Возникла необходимость изменить одно поле таблицы типа Alpha длиною 10 символов на тот же тип но длиною 15 символов и при этом чтобы сохранились значения в поле. Как это сделать без особых телодвижений (т.е. без создания новой таблицы и перекидывания туда значений).
Надумал код... но ничего не получается:
Table1.Active:= True;
For i:= 0 to Table1.FieldDefs.Count - 1 do
Begin
If Table1.FieldDefs.Items[i].Name = "Num" then
Begin
Table1.FieldDefs.Items[i].Size:= 10;
End;
Но ничего не происходит. Видно что я что-то не доделаю.
Пробовал вставдять строку Table1.FieldDefs.Update - не помогает...
← →
Skalp (2003-09-24 00:00) [1]Сорри, строку
Table1.FieldDefs.Items[i].Size:= 10
надо понимать
Table1.FieldDefs.Items[i].Size:= 15
очепятка :)
← →
Кщд (2003-09-24 06:43) [2]SQL, тот, что DDL не устраивает?
← →
ЮЮ (2003-09-24 07:42) [3]Если процедура разовая, то сделай в DataBase Desctope и не парься
Если же хочешь встроить в программу, то копай в сторону ВDE, реструкторизация таблиц
← →
Denizzz (2003-09-24 09:43) [4]
procedure ChangeField(Table: TTable; Field: TField; Rec: ChangeRec);
var
Props: CURProps;
hDb: hDBIDb;
TableDesc: CRTblDesc;
pFields: pFLDDesc;
pOp: pCROpType;
B: Byte;
begin
pFields := nil;
pOp := nil;
if not Table.Active then
raise EDatabaseError.Create("Table must be opened to restructure");
if not Table.Exclusive then
raise EDatabaseError.Create("Table must be opened exclusively" +
"to restructure");
Check(DbiSetProp(hDBIObj(Table.Handle), curxltMODE, Integer(xltNONE)));
Check(DbiGetCursorProps(Table.Handle, Props));
if (Props.szTableType <> szPARADOX) and (Props.szTableType <> szDBASE) then
raise EDatabaseError.Create("Field altering can only occur on Paradox" +
" or dBASE tables");
pFields := AllocMem(Table.FieldCount * sizeof(FLDDesc));
pOp := AllocMem(Table.FieldCount * sizeof(CROpType));
try
Inc(pOp, Field.Index);
pOp^ := crMODIFY;
Dec(pOp, Field.Index);
Check(DbiGetFieldDescs(Table.Handle, pFields));
Inc(pFields, Field.Index);
if (Length(Rec.szName) > 0) then
pFields^.szName := Rec.szName;
if (Rec.iType > 0) then
pFields^.iFldType := Rec.iType;
if (Rec.iSubType > 0) then
pFields^.iSubType := Rec.iSubType;
if (Rec.iLength > 0) then
pFields^.iUnits1 := Rec.iLength;
if (Rec.iPrecision > 0) then
pFields^.iUnits2 := Rec.iPrecision;
Dec(pFields, Field.Index);
for B := 1 to Table.FieldCount do begin
pFields^.iFldNum := B;
Inc(pFields, 1);
end;
Dec(pFields, Table.FieldCount);
FillChar(TableDesc, sizeof(TableDesc), #0);
Check(DbiGetObjFromObj(hDBIObj(Table.Handle), objDATABASE, hDBIObj(hDb)));
StrPCopy(TableDesc.szTblName, Table.TableName);
StrPCopy(TableDesc.szTblType, Props.szTableType);
TableDesc.iFldCount := Table.FieldCount;
TableDesc.pecrFldOp := pOp;
TableDesc.pFldDesc := pFields;
Table.Close;
Check(DbiDoRestructure(hDb, 1, @TableDesc, nil, nil, nil, False));
finally
if (pFields <> nil) then
FreeMem(pFields);
if (pOp <> nil) then
FreeMem(pOp);
end;
end;
Пример использования:
interface
...
type
ChangeRec = packed record
szName: DBINAME;
iType: Word;
iSubType: Word;
iLength: Word;
iPrecision: Byte;
end;
...
procedure TForm1.Button1Click(Sender: TObject);
var ch: ChangeRec;
begin
ch.szName:="Product";
ch.iType:=1;
ch.iLength:=20;
ChangeField(Table1,Table1.FieldByName("Product"),ch);
end;
Лучше эту процедуру (и подобные типа PackTable) в dll скомпилить и потом из нее вызывать.
← →
Val (2003-09-24 10:33) [5]>Skalp (23.09.03 23:58)
По поводу скудности - на необходимое вполне хватает. Не нужна дополнительная таблица при изменении типа поля.
Страницы: 1 вся ветка
Текущий архив: 2003.10.13;
Скачать: CL | DM;
Память: 0.46 MB
Время: 0.009 c