以下代码摘自 TDBBackup 2.0
// BDEDBBackup.pas
{ ================================================================================= }
<font color=red>function TBDEDBBackup.GetIndexDesc(ATableName: string): TIdxDescArray;
var
hIdxList: hDbicur;
IndexDesc: IDXDesc;
begin
SetLength(Result, 0);
try
// 注意: 这里的 ATableName 必须是一个完整的 Owner.Table 格式的表名
// 否则对 M$SQL 数据库将取不到索引列表
Check(DbiOpenIndexList(hDatabase, PChar(ATableName), nil, hIdxList));
while DbiGetNextRecord(hIdxList, DbiNoLock, @IndexDesc, nil) <> DbiErr_Eof do
begin
SetLength(Result, Length(Result) + 1);
Result[High(Result)] := IndexDesc;
end;
finally
Check(DbiCloseCursor(hIdxList));
end;
end;</font>
{ ================================================================================= }
function TBDEDBBackup.DoGetSQLScript(ATableName: string): string;
var
FieldDescs: TFLDDescArray;
IndexDescs: TIDXDescArray;
VCheckDescs: TVCHKDescArray;
function GetFieldName(AFieldNumber: Integer): string; // 根据 FieldNumber 取字段名
var
I: Integer;
begin
Result := '';
for I := Low(FieldDescs) to High(FieldDescs) do
with FieldDescs do
if iFldNum = AFieldNumber then
begin
Result := szName;
Break;
end;
end;
function FieldIsRequired(AFieldNumber: Integer): Boolean; // 根据 FieldNumber 确定字段是否必须
var
I: Integer;
begin
Result := False;
for I := Low(VCheckDescs) to High(VCheckDescs) do
with VCheckDescs do
if (iFldNum = AFieldNumber) and bRequired then
begin
Result := True;
Break;
end;
end;
function GetTableScript: string;
var
I: Integer;
FieldName: string;
FieldType: string;
UnitCount: Integer;
begin
Result := 'Create Table ' + FixTableName(ATableName) + '(';
for I := Low(FieldDescs) to High(FieldDescs) do
with FieldDescs, DataTypeList do
begin
if SQLAutoWrap then Result := Result + #13;
FieldType := IntToStr(iFldType);
try
UnitCount := StrToInt(Values[FieldType + ' UnitCount']);
except
UnitCount := 0;
end;
FieldName := szName;
if Pos(' ', FieldName) > 0 then FieldName := '"' + FieldName + '"';
Result := Result + ' ' + FieldName + ' ' + Values[FieldType];
case UnitCount of
1: Result := Result + Format('(%d)', [iUnits1]);
2: Result := Result + Format('(%d, %d)', [iUnits1, iUnits2]);
end;
if FieldIsRequired(iFldNum) then
Result := Result + ' ' + Values[DriverName + '_NotNull']
else
Result := Result + ' ' + Values[DriverName + '_Null'];
if I <> High(FieldDescs) then
Result := Result + ',';
end;
if SQLAutoWrap then Result := Result + #13;
Result := Result + ')' + SQLSeparator + #13;
end;
<font color=red>function GetIndexScript: string;
var
I: Integer;
J: Integer;
IndexName: string;
Unique: string;
begin
Result := '';
for I := Low(IndexDescs) to High(IndexDescs) do
with IndexDescs do
begin
if Result <> '' then Result := Result + #13;
if szName <> '' then // 索引名
IndexName := szName
else
IndexName := 'Primary';
if bUnique then
Unique := 'Unique'
else
Unique := '';
Result := Result
+ Format('Create %s Index %s on %s (',
[Unique, IndexName, FixTableName(ATableName)]);
for J := 0 to iFldsInKey - 1 do // 取索引字段信息
begin
Result := Result + GetFieldName(aikeyFld[J]);
if J <> iFldsInKey - 1 then Result := Result + ', ';
end;
Result := Result + ')' + SQLSeparator + #13;
end;
end;</font>
begin
FieldDescs := GetFieldDesc(ATableName);
<font color=red>IndexDescs := GetIndexDesc(ATableName);</font>
VCheckDescs := GetVCheckDesc(ATableName);
if SQLIncludeIndexes then
Result := GetTableScript + #13 + GetIndexScript
else
Result := GetTableScript;
end;