Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Сортировка списка GUID в памяти по алгоритму SQL Server

Delphi , Базы данных , Сортировка и Фильтр

В проекте, над которым я работаю, было бы полезно иметь возможность сортировать список GUID в памяти и сравнивать его с таблицей SQL Server, отсортированной по тем же GUID. К сожалению, когда отсортированный список возвращается из SQL Server, порядок не сразу очевиден.

Какой лучший способ отсортировать этот список в памяти так, чтобы порядок был таким же, как и в возвращенном SQL Server?

Например, запрос "SELECT ID FROM TABLE1 ORDER BY ID" возвращает:

A46030EC-BF3A-4F7C-88CC-00117DBC1A52
159A0A9D-18B7-4D6C-ABB3-005FAB666D91
3C58CFC5-1829-481C-9686-007CE71132B8
15A96D5F-DAFB-4EF1-9202-00B201CE5151
BCFDE733-0AB0-483F-B912-00BF93F6FA7E
6CC06558-7670-4879-9D3F-00CB3D3649BD

Для целей этого вопроса предположим, что у меня есть массив строк, содержащий значения GUID в следующем порядке:

159A0A9D-18B7-4D6C-ABB3-005FAB666D91
15A96D5F-DAFB-4EF1-9202-00B201CE5151
6CC06558-7670-4879-9D3F-00CB3D3649BD
8A9325AF-A84E-4BDB-AFA8-C9D09D7FC064
A46030EC-BF3A-4F7C-88CC-00117DBC1A52
BCFDE733-0AB0-483F-B912-00BF93F6FA7E

Я хочу увидеть, что одного из SQL-запроса не хватает, а один из него отсутствует. Самый быстрый способ очевиден - иметь оба списка отсортированными одинаково, но я не хочу выполнять запрос, подобный "SELECT ID FROM TABLE1 ORDER BY CAST(ID AS VARCHAR(100))", а предпочитаю исправить сортировку на стороне Delphi.

SQL Server сортирует GUID в следующем порядке: первые 4 байта (0-3), затем следующие 2 байта (4-5), затем следующие 2 байта (6-7), затем последние 2 байта (8-9) в обратном порядке, и finally the last 2 bytes (A-F) в обратном порядке. Это наиболее важные биты.

Вот как можно отсортировать список GUID в памяти в том же порядке, что и SQL Server, используя Delphi:

procedure SortGUIDs(arrGUIDs: TArray<string>);
var
  i, j: Integer;
  tempGUID: string;
begin
  SetLength(arrGUIDs, Length(arrGUIDs));
  for i := Low(arrGUIDs) to High(arrGUIDs) do
    for j := i + 1 to High(arrGUIDs) do
      if CompareGUIDs(arrGUIDs[i], arrGUIDs[j]) > 0 then
      begin
        tempGUID := arrGUIDs[i];
        arrGUIDs[i] := arrGUIDs[j];
        arrGUIDs[j] := tempGUID;
      end;
end;

function CompareGUIDs(guid1, guid2: string): Integer;
var
  bytes1, bytes2: array[0..15] of Byte;
begin
  Result := 0;
  for var i := 0 to 15 do
  begin
    bytes1[i] := GuidToByte(guid1, i);
    bytes2[i] := GuidToByte(guid2, i);
    if bytes1[i] < bytes2[i] then
      Exit(-1)
    else if bytes1[i] > bytes2[i] then
      Exit(1);
  end;
end;

function GuidToByte(guid: string; index: Integer): Byte;
begin
  Result := StrToByte(guid[index * 2 + 1] + guid[index * 2]);
end;

Этот код сначала преобразует GUID в массив байтов, а затем сравнивает каждый байт в обратном порядке, как это делает SQL Server. После сравнения всех байтов функция CompareGUIDs возвращает -1, если guid1 меньше guid2, 0, если они равны, или 1, если guid1 больше guid2. Функция SortGUIDs использует CompareGUIDs для сортировки списка GUID по алгоритму SQL Server.

Создано по материалам из источника по ссылке.

Практический вопрос о сортировке списка GUID в памяти в том же порядке, что и SQL Server, используя Delphi.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Сортировка и Фильтр ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-01-29 01:48:36/0.02472996711731/1