我有权检查所有外键约束,我的数据库有500个表,有很多fk约束的字段需要很长时间(10秒): 我在数据集的前部使用此函数,如下所示:
msg := check_foreign_key(Dataset,'employee',field_name);
if msg <> '' then
begin
ShowMessage(msg);
abort;
Exit;
end;
我怎样才能减少这个时间,这是我的功能:
function check_foreign_key(ds: TDataSet;table_name: string;var ret_field_name: string): string;
var
qry1,qry2: TUniQuery;
ref_table:String;
begin
Result := '';
qry1 := TUniQuery.Create(nil);
qry2 := TUniQuery.Create(nil);
try
qry1.Connection := my_db;
with qry1 do
begin
close;
SQL.Clear;
SQL.Add('select COLUMN_NAME,REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME');
SQL.Add('from INFORMATION_SCHEMA.KEY_COLUMN_USAGE');
SQL.Add('where TABLE_SCHEMA = ''' + my_db.Database + ''' and TABLE_NAME = ''' + table_name + '''');
SQL.Add('and referenced_column_name is not NULL');
Open;
end;
qry2.Connection := my_db;;
while not qry1.Eof do
begin
if not DataSet_Has_Field(ds,qry1.FieldByName('COLUMN_NAME').AsString) then
begin
qry1.Next;
Continue;
end;
if ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).IsNull then
begin
qry1.Next;
Continue;
end;
with qry2 do
begin
close;
SQL.Clear;
SQL.Add('select count(' + qry1.FieldByName('REFERENCED_COLUMN_NAME').AsString + ') as c from ' + qry1.FieldByName('REFERENCED_TABLE_NAME').AsString);
if (ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).DataType = ftString) or
(ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).DataType = ftMemo) or
(ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).DataType = ftWideString) then
SQL.Add('where ' + qry1.FieldByName('REFERENCED_COLUMN_NAME').AsString + '=''' + ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).AsString + '''')
else
SQL.Add('where ' + qry1.FieldByName('REFERENCED_COLUMN_NAME').AsString + '=' + ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).AsString);
Open;
if FieldByName('c').AsInteger = 0 then
begin
ref_table := qry1.FieldByName('REFERENCED_TABLE_NAME').AsString;
Result := 'code ' + ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).AsString + ' not exist in table ' + ref_table;
ret_field_name := qry1.FieldByName('COLUMN_NAME').AsString;
Break;
end
else
begin
close;
SQL.Clear;
SQL.Add('show fields from ' + qry1.FieldByName('REFERENCED_TABLE_NAME').AsString + ' like ''%active''');
Open;
ref_table := FieldByName('field').AsString;
if recordcount > 0 then
begin
close;
SQL.Clear;
SQL.Add('select ' + ref_table + ' from ' + qry1.FieldByName('REFERENCED_TABLE_NAME').AsString);
if (ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).DataType = ftString) or
(ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).DataType = ftMemo) or
(ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).DataType = ftWideString) then
SQL.Add('where ' + qry1.FieldByName('REFERENCED_COLUMN_NAME').AsString + '=''' + ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).AsString + '''')
else
SQL.Add('where ' + qry1.FieldByName('REFERENCED_COLUMN_NAME').AsString + '=' + ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).AsString);
Open;
if FieldByName(ref_table).AsString = 'n' then
begin
if ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).AsString <> VarToStr(ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).OldValue) then
begin
Result := 'code ' + ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).AsString + ' not active. ' + #13#10 +
'Field :' + qry1.FieldByName('COLUMN_NAME').AsString;
ret_field_name := qry1.FieldByName('COLUMN_NAME').AsString;
end;
end;
end;
end;
end;
qry1.Next;
end;
finally
FreeAndNil(qry1);
FreeAndNil(qry2);
end;
end;