foreignkey Mysql的Delphi检查数据集

foreignkey Mysql的Delphi检查数据集,mysql,delphi,Mysql,Delphi,我有检查所有外键约束的功能,我的数据库有500个表,有许多fk约束的字段需要很长时间(10秒): 我在数据集的发布前使用此功能,如下所示: msg := check_foreign_key(Dataset,'employee',field_name); if msg <> '' then begin ShowMessage(msg); abort; Exit; end; msg:=检查外键(数据集,'employee',字段名称); 如果ms

我有检查所有外键约束的功能,我的数据库有500个表,有许多fk约束的字段需要很长时间(10秒): 我在数据集的发布前使用此功能,如下所示:

  msg := check_foreign_key(Dataset,'employee',field_name);
  if msg <> '' then
  begin
    ShowMessage(msg);
    abort;
    Exit;
  end;
msg:=检查外键(数据集,'employee',字段名称);
如果msg“”那么
开始
ShowMessage(msg);
中止
出口
结束;
如何减少这一时间,这是我的职责:

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;
函数检查\u外键(ds:TDataSet;表\u名称:string;变量ret\u字段\u名称:string):string;
变量
qry1,qry2:查询;
参考表:字符串;
开始
结果:='';
qry1:=TUniQuery.Create(nil);
qry2:=TUniQuery.Create(nil);
尝试
qry1.连接:=my_db;
使用qry1 do
开始
接近;
SQL.Clear;
Add('select COLUMN_NAME,REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME');
Add('from INFORMATION\u SCHEMA.KEY\u COLUMN\u USAGE');
Add('where TABLE_SCHEMA='''+my_db.Database+''和TABLE_NAME='''+TABLE_NAME+''');
SQL.Add('and referenced_column_name不为NULL');
打开
结束;
qry2.连接:=my_db;;
而不是qry1.Eof do
开始
如果数据集\u没有\u字段(ds,qry1.FieldByName('COLUMN\u NAME').AsString),则
开始
qry1.下一步;
继续;
结束;
如果ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).IsNull,则
开始
qry1.下一步;
继续;
结束;
使用qry2 do
开始
接近;
SQL.Clear;
SQL.Add('select count('+qry1.FieldByName('REFERENCED_COLUMN_NAME').AsString+'))作为c从'+qry1.FieldByName('REFERENCED_TABLE_NAME').AsString'中选择);
如果(ds.FieldByName(qry1.FieldByName('COLUMN_NAME')).AsString.DataType=ftString)或
(ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString.DataType=ftMemo)或
(ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString.DataType=ftWideString)然后
SQL.Add('where'+qry1.FieldByName('REFERENCED_COLUMN_NAME').AsString+'='''+ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString.).AsString+'')
其他的
SQL.Add('where'+qry1.FieldByName('REFERENCED_COLUMN_NAME').AsString+'='+ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).AsString);
打开
如果FieldByName('c').AsInteger=0,则
开始
ref_table:=qry1.FieldByName('REFERENCED_table_NAME')。AsString;
结果:='code'+ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString)。AsString+'不存在于表'+ref_表中;
ret_field_name:=qry1.FieldByName('COLUMN_name')。AsString;
打破
结束
其他的
开始
接近;
SQL.Clear;
SQL.Add('show fields from'+qry1.FieldByName('REFERENCED_TABLE_NAME')。AsString+'like'%active');
打开
ref_table:=FieldByName('field')。AsString;
如果recordcount>0,则
开始
接近;
SQL.Clear;
SQL.Add('select'+ref_table+'from'+qry1.FieldByName('REFERENCED_table_NAME').AsString);
如果(ds.FieldByName(qry1.FieldByName('COLUMN_NAME')).AsString.DataType=ftString)或
(ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString.DataType=ftMemo)或
(ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString.DataType=ftWideString)然后
SQL.Add('where'+qry1.FieldByName('REFERENCED_COLUMN_NAME').AsString+'='''+ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString.).AsString+'')
其他的
SQL.Add('where'+qry1.FieldByName('REFERENCED_COLUMN_NAME').AsString+'='+ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).AsString);
打开
如果FieldByName(ref_table).AsString='n',则
开始
如果ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).AsString VarToStr(ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString).OldValue),则
开始
结果:='code'+ds.FieldByName(qry1.FieldByName('COLUMN_NAME').AsString)。AsString+'未激活。'+#13#10 +
'Field:'+qry1.FieldByName('COLUMN_NAME').AsString;
ret_field_name:=qry1.FieldByName('COLUMN_name')。AsString;
结束;
结束;
结束;
结束;
结束;
qry1.下一步;
结束;
最后
FreeAndNil(qry1);
FreeAndNil(qry2);
结束;
结束;

实际上这不是delphi的问题,mysql信息模式很慢。您是否尝试过分析您的
check\u foreign\u key
以找出什么消耗了它大部分的执行时间?在任何情况下,看起来您都应该能够在服务器上执行所有fk检查,而不必在客户机上检索它