Delphi检查外键Mysql的数据集

时间:2017-01-26 19:04:56

标签: mysql delphi

我有权检查所有外键约束,我的数据库有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;

0 个答案:

没有答案