Поиск нескольких полей в ADO с помощью C++Builder XE4

Я использую метод Locate для поиска в TADOTable, но он не работает с поиском по нескольким полям. (Я ищу прямо на TADOTable, поэтому не заинтересован в SQL в этом случае).

Следующий код прекрасно работает при использовании одного поля, но не работает с несколькими полями!

void __fastcall TForm1::Button1Click(TObject *Sender)
{
        TLocateOptions LOpts;
        LOpts.Clear();
        LOpts << loPartialKey;
        Variant VAR[1];
        VAR[0] = Variant(Edit1->Text);

        try{
          if ( ADOTable1->Locate("CompanyID;Supplier", VAR, LOpts) ){
            // Record found
          }
        }
        catch(...){}
}

1 ответ

Решение

Поиск нескольких полей в TADODataSet делается почти так же, как и с любым другим TDataSet, с использованием Locate функция и дополнительный TLocateOptions:

if ADODataSet1.Locate('CompanyID;Supplier', 
                      VarArrayOf([Edit1.Text, Edit2.Text]), 
                      [loPartialKey]) then
begin
  // Record found
end;

Как ваш комментарий указывает, что вы на самом деле используете C++Builder и TADOTable Вот пример, который работает и для него (скомпилированный и протестированный в C++Builder XE5 в новом приложении VCL Forms):

TLocateOptions Opts;
Opts.Clear();
Opts << loPartialKey;

Variant locateValues[2];
locateValues[0] = Variant(Edit1->Text);
locateValues[1] = Variant(Edit2->Text);

if (ADOTable1->Locate("CompanyID;Supplier", VarArrayOf(locateValues, 1), Opts))
{
  // Record found.
};

Ваш комментарий к исходному вопросу указывает на то, что вы действительно хотите выполнить поиск в двух столбцах, чтобы увидеть, соответствует ли какой-либо из них значению. Вы не можете сделать это с одним Locate, но вы можете сделать это с помощью нескольких вызовов (код Delphi - вы сможете легко конвертировать его в C++Builder, учитывая другие примеры здесь). Конечно, оба столбца должны иметь одинаковый тип данных - вы не можете искать в числовом поле и в символьном поле одно и то же числовое (или символьное) значение без преобразования чего-либо:

var
  LastName: Variant;
begin
  LastName := Edit1.Text;
  if ADOTable1.Locate('LastName', LastName, [loPartialKey]) or
     ADOTable1.Locate('CompanyName', LastName, [loPartialKey]) then
  begin
    // Record found
  end;

Другой альтернативой является использование Filter (опять же, Delphi-код - простой перевод C++Builder):

AdoTable1.Filter := 'LastName = ' + QuotedStr(Edit1.Text) +
                    ' or CompanyName LIKE "' + QuotedStr(Edit1.Text) + '%"';
AdoTable1.Filtered := True;
AdoTable1.First;
// Get key values needed to locate on a full key, and then clear the filter.
Другие вопросы по тегам