How can I use the Locate Method of a TADODataSet with non-ASCII data in Delphi 10.3

218 Views Asked by At

I have an MS SQL Server 2019 table that has a column named "Char" and it is defined as nvarchar(4).

In my sample Delphi 10.3.3 code, I have a line that says:

 found := ADODataSet1.Locate('Char', '⓪', []);

There is no record in the table with such a value, but when I execute the code, Locate returns True and positions to the first record in the result set. If I add a record with that value, Locate still returns True, but positions to the first record in the result set, not the record with the desired character.

With an ASCII character, the code works as expected.

Update:

The first record in my table has "0" in the Char column. If I delete that, then Locating "⓪" returns False. If I add "⓪" to the table then Locate finds that one, but if both "⓪" and "0" are included, then it finds the ASCII digit. If I try to locate "②", it returns the record with "2" in it. The Char column, by the way is a unique index on the table.

Steps to recreate problem.

  1. SQL Server 2019, default US installation

  2. Create table

    CREATE TABLE [dbo].[Things]( [Thing] nvarchar NOT NULL ) ON [PRIMARY]

I created a VCL application with a TADODataSet, a TMemo and a TButton

Here is the code for the button:

procedure TForm2.Button1Click(Sender: TObject);
{} procedure Add2Table(aString: string);
begin
  with ADODataSet1 do begin
    Insert;
    FieldByName('Thing').AsString := aString;
    Post;
    Memo1.Lines.Add('Added: ' + aString);
  end;
end;

const
  cTarget = '①';
begin
  with ADODataSet1 do begin
    Close;
    CommandText := 'Select * from Things';
    Open;
    Memo1.Clear;
    Memo1.Lines.Add('RecordCount ' + IntToStr(RecordCount));
    Add2Table('0');
    Add2Table('1');
    Add2Table('2');
    Add2Table('⓪');
    Add2Table(cTarget);
    Add2Table('②');

    Close; Open;
    Memo1.Lines.Add('Trying to locate: ' +  cTarget);
    if Locate('Thing', cTarget, []) then
      Memo1.Lines.Add(Format('Found %s in record %d', [
        FieldByName('Thing').AsString, Recno]))
    else
      Memo1.Lines.Add('Not found');
  end;
end;

When the program runs, instead of finding the target character, "①", it finds '1'.

0

There are 0 best solutions below